如何使用Q库,同时转换节点asynchronousfunction承诺?

如何在下面的代码中使用Promise?

function async_f1(callback) { setTimeout(function() { callback("Async function 1..."); }, 1000); } function async_f2(callback) { setTimeout(function() { callback("Async function 2!..."); }, 1000); } function async_f3(callback) { setTimeout(function() { callback("Second async function 3!..."); }, 1000); } function doAll() { async_f1(function(result1) { async_f2(function(result2) { async_f3(function(result3) { console.log("Final result:", result1 + " " + result2 + " " + result3); }) }) }); } doAll(); 

谢谢

请参阅文档 。

例如:

 var promise = Q.nfcall(someAsyncFunction, arg1, ...); 

这里是使用Q.nfcall承诺的工作片段:

 var Q = require('q'); var a = Q.nfcall(function async_f1(callback) { setTimeout(function() { callback(null, "Async function 1..."); }, 1000); }); var b = Q.nfcall(function async_f2(callback) { setTimeout(function() { callback(null, "Async function 2!..."); }, 1000); }); var c = Q.nfcall(function async_f3(callback) { setTimeout(function() { callback(null, "Second async function 3!..."); }, 1000); }); function doAll() { Q.all([a, b, c]).then(function(result) { console.log(result); }).fail(function(err) { console.log(err); }) } doAll(); 

这里是Q.denodeify版本:

 var Q = require('q'); var a = function async_f1(callback) { setTimeout(function() { callback(null, "Async function 1..."); }, 1000); }; var b = function async_f2(callback) { setTimeout(function() { callback(null, "Async function 2!..."); }, 1000); }; var c = function async_f3(callback) { setTimeout(function() { callback(null, "Second async function 3!..."); }, 1000); }; var a_promise = Q.denodeify(a); var b_promise = Q.denodeify(b); var c_promise = Q.denodeify(c); function doAll() { Q.all([a_promise(), b_promise(), c_promise()]).then(function(result) { console.log(result); }).fail(function(err) { console.log(err); }) } doAll(); 

我以前的尝试失败了,因为我错过了一个重要的观点:

为了Q.nfcall工作,你的callback必须使用 callback(error, data)模式。 以前我没有添加错误参数,所以我没有得到任何错误,但没有任何输出。 一旦我将其固定为callback(null, "Async function 1")它开始工作。

起初,你会想promisify你的function 。 为了与nodeback函数接口,你通常使用Q.denodeify ,但是你的示例函数总是把结果传回第一个参数。 所以我们需要编写自己的函数:

 function promisify(fn) { return function() { var args = Array.prototype.slice.call(arguments), ctx = this; return Q.Promise(function(resolve) { fn.apply(ctx, args.concat([resolve]); }); }; } 

并使用它

 var f1 = promisify(async_f1), f2 = promisify(async_f2), f3 = promisify(async_f3); 

有了这些,你可以用promise风格编写你的doAll函数:

 function doAll() { return f1().then(function(result1) { return f2().then(function(result2) { return f3().then(function(result3) { return "Final result:", result1 + " " + result2 + " " + result3; }); }); }).then(function(res) { console.log(res); }); } doAll(); 

如果callback金字塔对你来说看起来很奇怪,那么看看如何访问.then()链中的前一个promise结果? 。

但是,由于你的function实际上不依赖于其他的结果,你可以很容易地并行运行它们:

 function doAll() { return Q.all([f1(), f2(), f3()]).then(function(result) { console.log("Final result:", result1 + " " + result2 + " " + result3); }); }