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