最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Creating node library that support both node callbacks and promise with bluebird - Stack Overflow

programmeradmin0浏览0评论

I am creating a node module and I want to be able to support both node callback and Promise APIs. The library that I hear the best things about (mainly that is it the fastest) is bluebird. So after reading some docs and looking at some other libraries that are using bluebird, I thought this would be the cleanest way to get a method to support both node callback and Promise APIs:

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

However with this code, the callback is never executed. After some more research, I tried this:

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

With that code, both the node callback and Promise API works.

For reference, this is the isAllowed method:

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

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

Am I doing something wrong in the first code example or is the second example the real way of getting what I am looking for?

I am creating a node module and I want to be able to support both node callback and Promise APIs. The library that I hear the best things about (mainly that is it the fastest) is bluebird. So after reading some docs and looking at some other libraries that are using bluebird, I thought this would be the cleanest way to get a method to support both node callback and Promise APIs:

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

However with this code, the callback is never executed. After some more research, I tried this:

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

With that code, both the node callback and Promise API works.

For reference, this is the isAllowed method:

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

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

Am I doing something wrong in the first code example or is the second example the real way of getting what I am looking for?

Share Improve this question edited May 7, 2014 at 8:20 Esailija 140k23 gold badges279 silver badges328 bronze badges asked May 6, 2014 at 17:26 ryanzecryanzec 28.1k39 gold badges116 silver badges173 bronze badges 1
  • 1 isAllowed is a synchronous function, it makes no sense to do this – Esailija Commented May 7, 2014 at 8:09
Add a ment  | 

1 Answer 1

Reset to default 13

Your specific problem makes no sense (see my ment) so I'll just be generic. There are 2 ways to expose a dual promise/callback API.

First way is to have the same function support promises and callbacks at the same time, by returning a promise if callback parameter is not passed or using the callback if it is passed.

However this is hard to implement and can have some nasty problems when some arguments are optional.

To implement it, you do exactly the same thing as you would with a 100% promise function except you add a .nodeify at the end of the returned chain.

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

}

The second way is to define a normal callback api, and then just call promisifyAll. This is very easy to implement, in fact there is almost no reason to do it at all because the user can so easily promisify the module themselves if they use bluebird.

发布评论

评论列表(0)

  1. 暂无评论