让 Promise 等待 Chrome.runtime.sendMessage [英] Make Promise wait for a Chrome.runtime.sendMessage

查看:16
本文介绍了让 Promise 等待 Chrome.runtime.sendMessage的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直看到 Promise 与 setTimeout 一起工作,但我试图根据 chrome.runtime.sendMessage 返回给 Promise 的任何内容来制作它.

I've always seen Promise work with setTimeout, but I'm trying to make it based on whatever the chrome.runtime.sendMessage returns to the Promise.

我有一个内容脚本,一旦脚本完成,它就会执行这个功能.

I've got a content script that does this function once the script has been done.

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

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

I've got a background script that loops through every item in an array and uses one of its values to open a URL with chrome.tabs.update.

我想要做的是让异步函数等待内容脚本发送的消息,并且只有在收到消息后才继续下一次迭代,尽管我不知道如何实现这一点,因为我'只见过 setTimeout 的例子.

What I'm trying to do is make the async function wait for the Message the content script is sending and only continue with the next iteration once the message has been received, although I don't know how to implement this since I've only seen examples with setTimeout.

所以应该

  1. 打开数组中的第一项并停止
  2. 在该页面上执行内容脚本并在最后执行一个 sendMessage.
  3. 现在后台脚本应该等待接收到 sendMessage,然后再转到下一项.
  4. 使用 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"与承诺一起工作,您可以包装它:

It is easier to ask a content-script to do its job and answer when it finished.
To make "sendMessage" work with promises you can wrap it:

/**
 * 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');
            }
        });
    });
}

内容脚本应该是这样的:

The content-script should have something like this:

// 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;
});

这篇关于让 Promise 等待 Chrome.runtime.sendMessage的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆