我一直都看到Promise与setTimeout一起工作,但是我试图基于chrome.runtime.sendMessage返回Promise的任何东西来实现它。

我有一个内容脚本,脚本完成后便会执行此功能。

chrome.runtime.sendMessage({complete: true});

我有一个后台脚本,该脚本循环遍历数组中的每个项目,并使用其值之一来打开带有chrome.tabs.update的URL。

我想做的是让异步功能等待内容脚本正在发送的消息,并且仅在收到消息后才继续下一次迭代,尽管我不知道如何实现此目的,因为我只知道看到带有setTimeout的示例。

所以应该
  • 打开数组中的第一项并停止
  • 在该页面上执行内容脚本,并在最后执行sendMessage。
  • 现在,后台脚本应该在转到下一个项目之前,等待sendMessage的接收。
  • 一旦使用onMessage接收到sendMessage,它应该转到下一个项目,然后从步骤2开始重复

  • 这是后台脚本。
        chrome.storage.local.get('userItems', function(result) {
        console.log(result.userItems);
    
        function delay() {
          // I suppose I should do something with onMessage in the delay function
          return new Promise(resolve => setTimeout(resolve, 500));
        }
    
        async function delayedLog(item) {
          await delay();
    
          console.log(item);
          var url = "http://www.example.com/" + item.Category;
    
          chrome.tabs.update({
            url: url
          });
        }
    
        async function processArray(array) {
          for (const item of array) {
            await delayedLog(item);
          }
        }
    
        processArray(result.userItems);
    
        });
    

    最佳答案

    要求内容脚本完成工作并在完成时回答是容易的。
    为了使“sendMessage”与promise一起使用,您可以将其包装:

    /**
     * Promise wrapper for chrome.tabs.sendMessage
     * @param tabId
     * @param item
     * @returns {Promise<any>}
     */
    function sendMessagePromise(tabId, item) {
        return new Promise((resolve, reject) => {
            chrome.tabs.sendMessage(tabId, {item}, response => {
                if(response.complete) {
                    resolve();
                } else {
                    reject('Something wrong');
                }
            });
        });
    }
    

    内容脚本应具有以下内容:

    // waiting for tasks from background
    chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
        const item = msg.item;
    
        // Asynchronously process your "item", but DON'T return the promise
        asyncOperation().then(() => {
          // telling that CS has finished its job
          sendResponse({complete: true});
        });
    
        // return true from the event listener to indicate you wish to send a response asynchronously
        // (this will keep the message channel open to the other end until sendResponse is called).
        return true;
    });
    

    关于javascript - 让Promise等待Chrome.runtime.sendMessage,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52087734/

    10-11 13:46