Node.js中,q
可以方便地将回调大坑
转换成链式调用,极大地增强了代码的可读性,下面一段代码演示了q
在链式调用和异步调用中起到的作用。
源码
//app.js
var Q = require('q');
function func1(){
console.log('fun1 start');
var deferred = Q.defer();
deferred.resolve('func1 resolve');
console.log('func1 stop');
return deferred.promise;
}
function func2(value){
var deferred = Q.defer();
setTimeout(()=>{
console.log('fun2 start');
deferred.resolve(value + ', func2 resolve');
console.log('func2 stop');
}, 3000);// 3000ms后打印
return deferred.promise;
}
function func3(value){
var deferred = Q.defer();
setTimeout(()=>{
console.log('fun3 start');
deferred.resolve(value + ', func3 resolve');
console.log('func3 stop');
}, 1000);// 1000ms后打印
return deferred.promise;
}
function main(){
console.log('main start');
func1().then(func2).then(func3).done((value)=>{console.log('fulfilled, value = ' + value)}, (err)=>{console.log('rejected, err = ' + err);});
console.log('main stop');
}
main();
运行结果:
# npm install q --registry=https://registry.npm.taobao.org
[email protected] node_modules/q
# node app.js
main start
fun1 start
func1 stop
main stop
fun2 start
func2 stop
fun3 start
func3 stop
fulfilled, value = func1 resolve, func2 resolve, func3 resolve
结论
q
只能保证链式调用中的节点(本例中的then
和done
)之间是顺序执行的。这可以从func2
和func3
的执行输出得到验证:func2
先被执行,但是延时3000ms才打印;func3
后执行,只延时1000ms打印,从打印结果来看,func3
并没有先于func2
打印,即q
的链式调用中的节点执行顺序,取决于节点在调用链中出现的顺序,与节点本身的代码无关。q
的链式调用的执行是异步的。这可以从main stop
以后,才打印func2
和func3
和done
的执行结果得到验证。