【问题标题】:Node; Q Promise delay节点; Q 承诺延迟
【发布时间】:2017-05-08 08:33:37
【问题描述】:

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

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

这个的输出是:

> "THING 2"
> "THING 1"

问题:

1) 为什么Q 实现在对立即已知的值运行回调之前等待?为什么Q 不够聪明,无法让第一行在第二行运行之前同步发出其输出?

2) 输出"THING 2""THING 1" 之间的时间间隔是多少?是单进程tick吗?

3) 深深包裹在 promise 中的值是否存在性能问题?例如,Q(Q(Q("THING 1"))) 是否异步等待 3 倍的时间才能完成,即使它可以有效地同步解决?

【问题讨论】:

    标签: node.js promise q


    【解决方案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 在调用 then 的事件循环之后异步执行,并使用新堆栈。这可以通过“宏任务”机制(例如 setTimeout 或 setImmediate)或“微任务”机制(例如 MutationObserver 或 process.nextTick)来实现。由于 Promise 实现被认为是平台代码,它本身可能包含一个任务调度队列或调用处理程序的“蹦床”。

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

    已进行了广泛讨论,以确保此要求明确 - 请参阅:

    【讨论】:

    • 但是不能专门实现Q() 函数以返回最初标记为已解决的承诺吗?如果您正在使用 Promise,那么您不太可能依赖 Promise 之外的代码在其中的代码之前运行。 Q() 函数不能立即解决保存一个进程刻度吗?那么其他问题呢? :P
    • 啊,我明白了!你知道为什么这是规范的一部分吗?本质上,为什么规范会选择在值应该立即访问的情况下强制延迟?另外,我想这意味着Q(Q(Q(Q(Q(Q(Q(1))))))) 的履行将延迟 7 个进程滴答?
    • @GershomMaes 请参阅第 229 期“Promise/A+ 规范第 2.2.4 条背后的意图是什么?” - github.com/promises-aplus/promises-spec/issues/229 并查看我回答中所有链接中的讨论。
    • 似乎在讨论中有混乱,但我明白了。感谢您的回答! :)
    • 实际上 Q 有一个 Q.asap 函数可以做到这一点,但由于给定的原因它被弃用了。 “如果您正在使用 Promise,那么您不太可能依赖 Promise 之外的代码在其中的代码之前运行” - 假设您 a) 很好地理解了 Promise b)不要犯错误,并且 c) 喜欢在竞争条件发生时对其进行调试。确保一致性并避免容易出错的情况是更好的主意。单个 microtick 延迟绝对不会影响性能。
    猜你喜欢
    • 2013-09-11
    • 2014-03-23
    • 2015-06-22
    • 2015-03-08
    • 1970-01-01
    • 2015-03-27
    • 2023-03-21
    • 1970-01-01
    相关资源
    最近更新 更多