节点; Q承诺延迟

时间:2016-12-22 16:37:47

标签: node.js promise q

以下是一些基于我在以下示例中注意到的行为的简单问题:在节点中运行:

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

这个输出是:

> "THING 2"
> "THING 1"

的问题:

1)为什么Q实现了在对一个立即知道的值运行回调之前等待?为什么没有Q足够智能以允许第一行在第二行运行之前同步发出其输出?

2)输出"THING 2""THING 1"之间的时间间隔是多少?这是一个单一的流程吗?

3)对于承诺中深深包含的价值观,是否存在业绩问题?例如,Q(Q(Q("THING 1")))是否异步等待3次完成,即使它可以有效地同步解析?

1 个答案:

答案 0 :(得分:1)

这实际上是故意的。无论值是否已知,都要使其保持一致。这样只有一个评估顺序,你可以依赖这样一个事实,即无论承诺是否已经解决,该顺序将是相同的。

另外,这样做可以编写代码来测试承诺是否已经解决,并且在设计时不应该知道并采取行动。

这就像做回调式代码一样:

function fun(args, callback) {

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

以便任何使用以下方式调用它的人:

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

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

规范

请参阅Promises/A+ SpecificationThe then Method部分,第4点:

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

onFulfilledonRejected

另请参阅the note 1

  

此处"平台代码"表示引擎,环境和承诺实现代码。实际上,这个要求确保onFulfilled和onRejected异步执行,然后调用事件循环,然后调用新堆栈。这可以通过"宏任务"来实现。机制,如setTimeout或setImmediate,或与"微任务" MutationObserver或process.nextTick等机制。由于promise实现被认为是平台代码,它本身可能包含任务调度队列或" trampoline"在其中调用处理程序。

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

为了确保这一要求是明确的,我们进行了广泛的讨论 - 见: