0

I'm working on a Chrome extension. I'm a little confused on the callbacks. I have some situations where I would need to have multiple async calls. For example, I have

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {

}

Inside of this I need to make a call to chrome.storage.local.remove and chrome.storage.local.set. The response to the message would be based on the results of the remote and set. If they fail of course a different response would be sent.

How should this be handled?

user568551
  • 337
  • 3
  • 11
  • All you need in addition to the classic multiple-asynchronous-callbacks topic above is to `return true` from onMessage listener which will enable you to call sendResponse at a later time. – wOxxOm Oct 21 '20 at 04:33

1 Answers1

0

I recommend you build your chrome extension using the standard js tools (webpack/babel). Multiple callbacks are handled quite easily with modern syntax like this:

const setStore = (data) => {
    return new Promise((resolve) => chrome.storage.local.set(data, resolve));
};

const async handleAsyncMessage = (request, sender, sendResponse) => {
    await doSomething();
    await setStore({ myKey: 1 });

    //or if you dont want them to run sequentially

    await Promise.all([
      doSomething(),
      doAnotherThing(),
    ]);
};

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  handleAsyncMessage(request, sender, sendResponse);

  return true;
});

You can wrap chrome.storage.local.remove and chrome.storage.local.set in a function that returns a promise that resolves when their callback is executed. This will keep your code easier to read than callback hell.

smallnoyd
  • 93
  • 7
  • This won't be able to send a response because the listener needs to return a literal `true` to keep the channel open, but your listener returns a Promise. Chrome extension API doesn't understand Promise. The solution is either to use a separate `async` function or use Promise explicitly or load Mozilla's `browser` namespace polyfill which enables us to use an `async` listener directly like you did. – wOxxOm Oct 21 '20 at 04:30
  • @wOxxOm you are mostly correct, thanks for the correction: the OP will need to wrap it in a regular function but the callback should only return literal true if the handler will be asynchronous. Our code has a big switch statements and for messages that can be handled synchronously, we dont return true. – smallnoyd Oct 21 '20 at 21:05
  • Well, the OP explicitly stated that they will be using asynchronous stuff inside so... – wOxxOm Oct 22 '20 at 04:16