3

我正在创建一个节点模块,我希望能够同时支持节点回调和 Promise API。我听到最好的东西(主要是它最快的)的图书馆是bluebird。因此,在阅读了一些文档并查看了其他一些使用 bluebird 的库之后,我认为这是获得支持节点回调和 Promise API 的方法的最干净的方法:

this.isAllowed = function(role, resource, permission, callback) {
  var isAllowedAsync = bluebird.promisify(isAllowed);
  return isAllowedAsync(role, resource, permission).nodeify(callback);
};

但是,使用此代码,永远不会执行回调。经过更多研究,我尝试了这个:

this.isAllowed = function(role, resource, permission, callback) {
  return new bluebird(function (resolve, reject) {
    resolve(isAllowed(role, resource, permission));
  }).nodeify(callback);
};

使用该代码,节点回调和 Promise API 都可以工作。

作为参考,这是 isAllowed 方法:

var isAllowed = function(role, resource, permission) {
  if(!lists[role] || !lists[role][resource]) {
    return false;
  }

  return lists[role][resource].indexOf(permission) !== -1;
};

我在第一个代码示例中做错了什么,还是第二个示例是获得我正在寻找的东西的真正方法?

4

1 回答 1

13

你的具体问题没有意义(见我的评论)所以我只是笼统的。有两种方法可以公开双重承诺/回调 API。

第一种方法是让相同的函数同时支持 Promise 和回调,如果未传递回调参数则返回一个 Promise,或者如果传递了回调则使用回调。

然而,这很难实现,并且当某些参数是可选的时可能会出现一些令人讨厌的问题。

要实现它,您所做的事情与使用 100% 承诺函数完全相同,只是.nodeify在返回链的末尾添加 a 。

// Note however this doesn't work if some arguments before 
// `callback` are optional
function dualApi(..., callback) {
    // acting as if you would never support callbacks at all
    return getPromise()
           .then(...) 
           .then(...)
           .then(...)
            // .nodeify at the end of the chain, NOWHERE else
           .nodeify(callback)

}

第二种方式是定义一个普通的回调api,然后调用promisifyAll. 这很容易实现,实际上几乎没有理由这样做,因为如果用户使用 bluebird,他们可以很容易地自己承诺模块。

于 2014-05-07T08:18:46.427 回答