Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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

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.

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.

So it should

  1. Open the first item in the array and stop
  2. Execute the content script on that page and do a sendMessage at the end.
  3. Now the background script should be waiting for the sendMessage to be received before going to the next item.
  4. Once the sendMessage has been received with onMessage it should go to the next and item and repeat from step 2

This is the background script.

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

    });
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
528 views
Welcome To Ask or Share your Answers For Others

1 Answer

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...