7

I have several async functions running. I want to wait for them all to finish before taking the next steps. Here's my code that I'm using to get all of the key/values from chrome.storage and the Promise.all() implementation.

var promise1 = Promise.resolve(3);
var promise2 = 42;
var promise3 = new Promise(function(resolve, reject) {
  setTimeout(resolve, 100, 'foo');
});

var getAll = chrome.storage.sync.get(function(result) {
  console.log(result)
});

Promise.all([promise1, promise2, promise3, getAll]).then(function(values) {
  console.log(values); // [3, 42, "foo", undefined]
});

This doesn't work unfortunately. It returns undefined.

Most of the code above is taken from MDN here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

jkupczak
  • 2,891
  • 8
  • 33
  • 55
  • chrome.storage.sync.get doesn't return anything as you can see in the documentation. The simplest solution is to use Mozilla WebExtension polyfill. – wOxxOm Apr 16 '18 at 04:11
  • FWIW, this should be coming to Chrome finally: https://bugs.chromium.org/p/chromium/issues/detail?id=328932 – John Jones Sep 12 '21 at 06:48

2 Answers2

13

The chrome.* API does not support promises, it uses async callbacks.
But you can promisify your call to chrome.storage.sync.get:

var getAllPromise = (function() {
    return new Promise(function(resolve) {
        chrome.storage.sync.get(function(result) {
            resolve(result);
        });
    });
})();

Promise.all([getAllPromise]).then(...);
Gangula
  • 5,193
  • 4
  • 30
  • 59
Denis L
  • 3,209
  • 1
  • 25
  • 37
0

As of July 29, 2022, according to chrome.storage documentation, it seems the chrome.storage API (manifest V3) still does not use promises with get and set calls (note the "pending" status of their Promise-based return types). However, that documentation does show how to promisify their code including error handling. (I would have just linked to this in a comment but I don't have the rep)

function getAllStorageSyncData() {
    // Immediately return a promise and start asynchronous work
    return new Promise((resolve, reject) => {
    // Asynchronously fetch all data from storage.sync.
    chrome.storage.sync.get(null, (items) => {
        // Pass any observed errors down the promise chain.
        if (chrome.runtime.lastError) {
        return reject(chrome.runtime.lastError);
        }
        // Pass the data retrieved from storage down the promise chain.
        resolve(items);
    });
    });
}

Note the part with chrome.runtime.lastError that returns via the promise's reject callback.

Gangula
  • 5,193
  • 4
  • 30
  • 59
wraiford
  • 181
  • 1
  • 5