是否有已弃用的 deferred.callback 的替代品?

Is there a replacement for the deprecated deferred.callback?

问题

我发现以下相当冗长的模式通常出现在我的代码中,当我包含为我提供难以实现的对象的库时 promisify:

var object = crummyLibrary.create();
return new Promise(function(resolve, reject){
  object.method('foo', function(err, bar){
    if(err){
      reject(err);
    }else{
      resolve(bar);
    }
  });
});

这在 Promise.defer() 中不那么冗长:

var deferred = Promise.defer();
object.method('foo', deferred.callback);
return deferred.promise;

但现在已弃用(有充分的理由),但我还没有找到该模式的良好替代品。我知道有这个:

return Promise.promisify(object.method, object)('foo');

但由于 context/receiver.

的传递,感觉很笨拙。

我在找什么

我希望有一些东西可以取代旧的 deferred.callback,也许是这样的:

var promise = new Promise;
object.method('foo', promise.callback);
return promise;

或者可能:

return new Promise(function(resolve, reject, callback){
  object.method('foo', callback);
});

或者有人向我指出我一直 "doing it wrong"。

好吧,promisify 应该在您的应用程序初始化时调用一次。您可以使用 promisifyAll 立即将整个 API 转换为 promisified API。

Promise.promisifyAll(app.auth);

这将允许您在以后的任何时间在 app.auth 上使用任何方法作为 promise 返回方法:

app.auth.authenticateAsync("local").then(function(res){ // preserves context
    // handle result
});

另请注意,promisifypromisifyAll 比使用 new Promise 和 promise 自己要快得多,因为它们使用动态重新编译技术和其他各种优化,因此最好使用它们(但仅在初始化时)。

从 2.9.0 开始,Bluebird 附带了一个 .fromNode 方法,可以更快地动态承诺不良行为的库:

Promise.fromNode(object.method.bind(object, "foo"))

我想可以实现如下内容:

return Promise.fromNodeFunction(function(callback){
  object.method('foo', callback);
});

只需要考虑更好的名字,不要那么冗长...

自己实现:

Promise.fromNodeFunction = function(resolver) {
    var d = Promise.defer();
    try {
        resolver(d.callback);
    } catch (e) {
        d.reject(e);
    }
    return d.promise;
};

这是最可取的,因为它现在是 3 行,但是使用箭头功能它是一行:

return Promise.fromNodeFunction(callback => object.method("foo", callback))

它与 bind 一起工作也很好:

return Promise.fromNodeFunction(object.method.bind(object, "foo"))