【问题标题】:Promisify chrome API using Bluebird使用 Bluebird 承诺 chrome API
【发布时间】:2018-02-01 13:16:43
【问题描述】:

我正在尝试使用 Bluebird.js 承诺 chrome.storage.sync.get。我看到 bluebird http://bluebirdjs.com/docs/working-with-callbacks.html 网站上的所有示例都使用 Promise.promisify(require(someAPI))。我试着做 const storageGet = Promise.promisify(chrome.storage.sync.get);(如果这会影响任何事情,我没有要求),然后调用

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

控制台错误是

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

我的理解(对 Promises 和 bluebird 的理解很少)是 storageGet 被传递了错误的参数?但是 chrome.storage.sync.get 需要传递一个字符串和一个回调函数,所以我不太确定出了什么问题。此外,我可能完全不了解我对 chrome 存储的承诺。

我知道http://bluebirdjs.com/docs/api/promise.promisifyall.html#option-promisifier 有一个带有 chrome 承诺的示例,但老实说,我不太熟悉承诺以了解该示例中发生了什么。

我是否应该以某种方式承诺 Chrome 存储而不是我正在做的方式?

【问题讨论】:

    标签: javascript google-chrome async-await bluebird


    【解决方案1】:

    更通用一点,在设置chrome.runtime.lastError 时会捕获错误。

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

    【讨论】:

      【解决方案2】:

      您想用 Bluebird 承诺的函数的回调 API 必须符合 NodeJS 回调约定:“错误优先,单参数”(如 HERE 所述)。根据storage sync documentation,其 API 不符合 Bluebird 要求的 API:

      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) {...};*/
      

      根本没有错误参数。这种方法甚至没有抛出任何错误。它只公开结果。您可以通过使用Promise 包装给定方法轻松地将其转换为基于 Promise 的 API:

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

      【讨论】:

        猜你喜欢
        • 2016-07-27
        • 1970-01-01
        • 2014-07-15
        • 1970-01-01
        • 2014-09-07
        • 2016-04-10
        • 1970-01-01
        • 2016-02-08
        • 2015-10-23
        相关资源
        最近更新 更多