在promise库中,bluebird具有函数promisifyAll或其他类似的库,声称将具有回调模式的异步函数转换为基于promise的ie。 resolve()
,reject()
或done()
..那么它是如何运作的?
例如:
function myAsync1 (data, url, callBack) {...}
如果我把它放在
中Promise.promisify(myAsycn1);
然后我的功能会像这样工作..
myAsync1('{..}', 'http://..').then(function(){...});
这一直困扰着我。是否存在异步非承诺库或函数需要遵循的模式Bluebird promisifyAll将它们转换为基于promises的方法,或者有一些魔法可以转换它们。
如果没有那么有什么要求以及它如何与mongodb等现有的库一起使用
答案 0 :(得分:22)
是否存在异步非承诺库或函数需要遵循的模式Bluebird promisifyAll将它们转换为基于promises的方法
是的,有一种模式。它转换的函数必须将回调作为最后一个参数。此外,它必须将错误作为回调的第一个参数传递(null
,如果没有错误),返回值作为第二个参数。
由于优化,BlueBird promisify
函数很难遵循,因此我将展示一种可以编写的简单方法:
function promisify(fn) {
return function() {
var that = this; // save context
var args = slice.call(arguments); // turn into real array
return new Promise(function(resolve, reject) {
var callback = function(err, ret) { // here we assume the arguments to
// the callback follow node.js
// conventions
if(err != undefined) {
reject(err);
} else {
resolve(ret);
}
};
fn.apply(that, args.concat([callback])); // Now assume that the last argument will
// be used as a callback
});
};
}
现在我们可以通过循环遍历目标对象中的函数并在每个函数上使用promisifyAll
来实现promisify
。
答案 1 :(得分:3)
promisifyAll()
方法将整个模块或对象作为参数进行调用。这意味着对象的每个属性的副本都是使用Async
后缀创建的,这实际上是同一方法的默认版本,即您可以使用.then()
或.done()
方法就可以了。
例如,如果doSomething()
模块中有someModule
方法,则在调用Promise.promisifyAll(someModule)
后,将在名为doSomethingAsync()
的模块中创建新方法。你可以这样使用它:
var someModule = require('some-module');
Promise.promisifyAll(someModule);
someModule.doSomethingAsync().then(function(result) {
// do whatever you want with result, this function runs after doSomthingAsync()
// is finished and the returned value is stored in 'result' variable.
});
查看bluebird API documentation了解详情。