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
的執行結果得到驗證。