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

查看:146
本文介绍了让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"与Promise一起使用,您可以将其包装:

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天全站免登陆