[英]Are chained commands always executed in order?
在node.js中編碼(這是異步的)時,我可以依賴我的鏈式命令按順序執行嗎?
var x=new MyObject();
x.start().doAThing().stop()
將先start
運行,然后是doAThing
然后stop
?
這取決於這些功能正在做什么。 除非您使用回調,否則命令將按順序執行。 但是,如果start()函數的邏輯需要異步調用,則只有在調用完成后結果才可用。 這意味着后續的doAThing()函數不能在start()函數中使用異步調用的結果。
tl; dr技術上,是的,但如果鏈中的某些函數是異步的,您可能需要考慮以不同方式組織代碼。
例如,序列x.start().doAThing().stop()
中的每個方法都是一個方法調用,它需要一些對象來操作。 為了調用doAThing()
,JavaScript VM必須首先評估x.start()
,然后查找doAThing
函數,然后它才能開始執行doAThing
的主體。
什么會doAThing
做可以根據價值是完全不同的x.start()
MyObject.prototype.start = function () {
if (/* condition */) {
return {
doAThing: function () {
return {
stop: function () {
console.log('path1');
}
};
}
};
}
else {
return {
doAThing: function () {
return {
stop: function () {
console.log('path2');
}
};
}
};
}
};
但是,您的函數可以啟動可能無序發生的異步任務。
MyObject.prototype.start = function () {
setTimeout(function () {
// This will happen out-of-order, usually after `stop` returns!
console.log('timed out');
}, 0);
return {
doAThing: function () {
return {
stop: function () {
console.log('stop');
}
};
}
};
};
請參閱jsbin 。 輸出:
stop
timed out
如果必須鏈接異步函數,則使用回調,promise或生成器重寫代碼。 例如,承諾:
var start = function (obj) {
return new Promise(function (resolve) {
setTimeout(function () {
// This will happen in order.
console.log('timed out');
resolve(obj);
}, 0);
});
};
var doAThing = function (obj) {
return Promise.resolve(obj);
};
var stop = function (obj) {
// Synchronous functions are fine, too.
console.log('stop');
};
該鏈將按順序執行這些功能:
Promise.resolve(x)
.then(start)
.then(doAThing)
.then(stop);
輸出:
timed out
stop
從技術上講,答案總是肯定的。 當x.start()
着火時,如果它執行io操作,Node的運行時將創建一個線程來執行該操作,因此異步,start仍然立即被觸發, x.start().doAThing()
將在x.start()
返回時x.start()
。 但是,asynch io可以在函數返回后返回響應,因此如果它是異步的, .doAThing()
將不會有響應。 這就是asynch函數使用回調/ promises / ES7異步函數的原因,技術上也可以使用ES6生成器,它可以訪問io響應。 只要它不是io操作,Nodejs就是同步。
所以
function start(){
var a = 1 + 1;
return {
doAthing: function(){ return a;}
};
}
將完全同步。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.