简体   繁体   中英

Promisify chrome API using Bluebird

I'm trying to promisify chrome.storage.sync.get using Bluebird.js. I see that all the examples on the bluebird http://bluebirdjs.com/docs/working-with-callbacks.html site use Promise.promisify(require(someAPI)) . I tried doing const storageGet = Promise.promisify(chrome.storage.sync.get); ( I don't have a require if that affects anything), and then calling

async function() {
  return await storageGet('config', function (result) {
    // do stuff
  })
};

Console error was

Unhandled rejection Error: Invocation of form get(string, function, function) 
doesn't match definition get(optional string or array or object keys, function 
callback)

My understanding (granted little understanding of Promises and bluebird) is that storageGet is being passed the wrong parameters? But chrome.storage.sync.get needs to be passed a string and a callback function so I'm not particularly sure what's going wrong. Also I could be completely off in how I'm promisifying chrome storage.

I am aware that there is an example with chrome promisifying at http://bluebirdjs.com/docs/api/promise.promisifyall.html#option-promisifier , but I'm honestly not too familiar with promises to understand what's going on in that example.

Is there a certain way I should be promisifying chrome storage than the way I'm doing it?

Callback API of function that you want to promisify with Bluebird has to conform to the NodeJS callback convention: "error-first, single-parameter" (as stated HERE ). According to the storage sync documentation its API does not conform to the one required by Bluebird:

StorageArea.get(string or array of string or object keys, function callback)

/* Callback with storage items, or on failure (in which case runtime.lastError will be set).

The callback parameter should be a function that looks like this:

function(object items) {...};*/

There's no error parameter at all. This method is not even throwing any error. It exposes only the result. You can easily turn it into Promise-based API by wrapping given method with Promise :

function getFromStorageSync(key) {
  return new Promise(function(resolve) {
    chrome.storage.sync.get(key, function(items) {
      resolve(items)
    })
  })
}

getFromStorageSync('someKey').then(function(items) { console.log(items) })

A bit more generic and will catch errors when chrome.runtime.lastError is set.

/**
 * Converts asynchronous chrome api based callbacks to promises
 *
 * @param {function} fn
 * @param {arguments} arguments to function
 * @returns {Promise} Pending promise returned by function
 */
var promisify = function (fn) {
  var args = Array.prototype.slice.call(arguments).slice(1);
  return new Promise(function(resolve, reject) {
    fn.apply(null, args.concat(function (res) {
      if (chrome.runtime.lastError) {
        return reject(chrome.runtime.lastError);
      }
      return resolve(res);
    }));
  });
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM