节点; Q承诺延期

以下是一些简单的问题,这些问题基于我在下面的节点中运行的示例中的行为:

Q('THING 1').then(console.log.bind(console)); console.log('THING 2'); 

这个输出是:

 > "THING 2" > "THING 1" 

问题:

1)为什么Q在执行callback之前等待立即知道的值? 为什么Q不够聪明,让第一行在第二行之前同步发出输出?

2)输出"THING 2""THING 1"之间的时间差是多less? 这是一个单一的过程?

3)对承诺中包含的价值观是否会有性能问题? 例如, Q(Q(Q("THING 1")))asynchronous地等待3倍的时间来完成,即使它可以被有效地同步解决?

这实际上是有目的地完成的。 无论价值是否已知,都要保持一致。 这样只有一个评价顺序,你可以依靠这个事实,不pipe承诺是否已经解决了,那个顺序也是一样的。

另外,如果这样做,就可以写一个代码来testing这个承诺是否已经解决了,而且在devise上它不应该被认识和采取行动。

这就像做callback式代码一样:

 function fun(args, callback) { if (!args) { process.nextTick(callback, 'error'); } // ... } 

所以任何与之通话的人:

 fun(x, function (err) { // A }); // B 

可以确定A永远不会在B之前运行。

规格

请参阅承诺/ A +规范 , then方法部分,点4:

在执行上下文堆栈只包含平台代码之前,不能调用onFulfilledonRejected

另见附注1 :

这里的“平台代码”是指引擎,环境和承诺的实现代码。 在实践中,这个要求确保了onFulfilled和onRejectedasynchronous执行,在事件循环开始之后被调用,并且有一个新的堆栈。 这可以使用诸如setTimeout或setImmediate之类的“macros任务”机制,或者使用诸如MutationObserver或process.nextTick的“微任务”机制来实现。 由于承诺实现被视为平台代码,因此它本身可能包含一个任务调度队列或“蹦床”,其中调用了处理程序。

所以这实际上是规范要求的。

这是广泛讨论,以确保这个要求是明确的 – 见: