在 chrome 扩展中传递消息时如何处理异步请求

How to handle async requests when message passing within chrome extensions

我正在构建一个 chrome 扩展,需要从 background.js 中的 google 云 Firestore 获取数据,然后再将返回的数据作为消息发送到 popup.js。

这就是 background.js 的样子:

  //background.js

  chrome.runtime.onMessage.addListener((msg, sender, resp) => {
    if (msg.command == 'fetch') {
      const listData = fetchListTitles();
      resp({
        type: 'result',
        status: 'success',
        data: listData,
        request: msg,
      });
      return true;
    }
  });
} catch (e) {
  console.error(e);
}

//get firestore data function
const fetchListTitles = async () => {
    let listTitles = [];
    const q = query(
      collectionGroup(db, 'Lists'),
      where('author', '==', 'placeholder')
    );

    const temp = await getDocs(q);

    temp.docs.map((doc) => {
      listTitles.push(linksToJSON(doc));
    });
    console.log(listTitles);
    return listTitles;
  };

这就是 popup.js 的样子

  //popup.js
  chrome.runtime.sendMessage({ command: 'fetch' }, (resp) => {
      if (resp.data) {
        console.log('popup', resp);
        setListTitles(resp.data);
      }
    });

当我读出或console.log返回的数据时,我没有看到friestore返回的任何数据。但是,在 background.js 中,我可以看到我从 fetchListTitles 函数 console.log 返回的数据

fetchListTitles 是用 async 关键字声明的,这意味着它总是 returns 一个 Promise。
Chrome 扩展无法通过消息发送 Promise。

你需要在Promise fullfilled之后发送response:

chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  if (msg.command === 'fetch') {
    fetchListTitles().then(listData => sendResponse({
      type: 'result',
      status: 'success',
      data: listData,
      request: msg,
    }));
    return true; // keeps the channel open for sendResponse
  }
});

另见