在node.js中编码(这是异步的)时,我可以依赖我的链式命令按顺序执行吗?
var x=new MyObject();
x.start().doAThing().stop()
首先start
先运行,然后doAThing
然后stop
?
答案 0 :(得分:2)
这取决于这些功能正在做什么。除非您使用回调,否则命令将按顺序执行。但是,如果start()函数的逻辑需要异步调用,则只有在调用完成后结果才可用。这意味着后续的doAThing()函数不能在start()函数中使用异步调用的结果。
答案 1 :(得分:1)
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
如果必须链接异步函数,则必须使用回调,承诺或生成器重写代码。例如,使用承诺:
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
答案 2 :(得分:1)
从技术上讲,答案总是肯定的。当exit
立即着火时,如果它执行io操作,Node的运行时将创建一个线程来执行该操作,因此异步,start仍然立即被触发,x.start()
将在x.start().doAThing()
返回时开火。但是,asynch io可以在函数返回后返回响应,因此如果它是异步的,x.start()
不会有响应。这就是asynch函数使用回调/ promises / ES7异步函数的原因,技术上也可以使用ES6生成器,它可以访问io响应。只要它不是io操作,Nodejs就是同步。
所以
.doAThing()
将完全同步。