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
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);
});
runtime. onMessage API functions. The chrome.runtime.sendMessage function is used to send one time messages from one part of the extension to another part. The function receives a message object which can be any JSON serializable object and an optional callback to handle the response from the other part.
The chrome.runtime.sendMessage method must not return anything (because Chrome doesn't either). Currently we return a Promise if the response callback is not set, which should be undefined. How do we end up returning a promise? (In reply to Bill McCloskey (:billm) from comment #4 ) > How do we end up returning a promise?
Promises were introduced into Chrome not long after they were included in the ES6 specification. They are an important feature of modern JavaScript, providing benefits such as: In Manifest V2 extension developers could use libraries to "promisify" Chrome's extensions APIs.
Extensions APIs don't set chrome.runtime.lastError when you use a promise; instead they provide the error as an argument to the function in the .catch (). In simpler cases with a single promise, you can instead supply your error handler as the second parameter to .then () instead of chaining to a .catch ().
runtime.sendMessage () Sends a single message to event listeners within your extension or a different extension. If sending to your extension, omit the extensionId argument. The runtime.onMessage event will be fired in each page in your extension, except for the frame that called runtime.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;
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With