节点; Q承诺延迟 [英] Node; Q Promise delay

查看:162
本文介绍了节点; Q承诺延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Here are some simple questions based on behaviour I noticed in the following example running in node:

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

此输出为:

> "THING 2"
> "THING 1"

问题:

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

Questions:

1) Why is Q implemented to wait before running the callback on a value that is immediately known? Why isn't Q smart enough to allow the first line to synchronously issue its output before the 2nd line runs?

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

2) What is the time lapse between "THING 2" and "THING 1" being output? Is it a single process tick?

3)能否将绩效深深包裹在承诺中而产生绩效问题?例如,Q(Q(Q("THING 1")))是否可以异步地等待3倍的时间才能完成,即使它可以被有效地同步解决?

3) Could there be performance concerns with values that are deeply wrapped in promises? For example, does Q(Q(Q("THING 1"))) asynchronously wait 3 times as long to complete, even though it can be efficiently synchronously resolved?

推荐答案

这实际上是有意完成的.无论值是否已知,都是为了使其一致.这样,只有一个评估顺序,您可以依赖以下事实:无论承诺是否已兑现,该顺序都是相同的.

This is actually done on purpose. It is to make it consistent whether or not the value is known or not. That way there is only one order of evaluation and you can depend on the fact that no matter if the promise has already settled or not, that order will be the same.

否则,否则将可以编写代码来测试诺言是否已兑现,并且通过设计不应当知道并兑现诺言.

Also, doing it otherwise would make it possible to write a code to test if the promise has settled or not and by design it should not be known and acted upon.

这几乎与像这样的回调样式代码一样:

This is pretty much the as doing callback-style code like this:

function fun(args, callback) {

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

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

so that anyone who calls it with:

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

可以确保A永远不会在B之前运行.

can be sure that A will never run before B.

请参见承诺/A +规范

See the Promises/A+ Specification, The then Method section, point 4:

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

onFulfilledonRejected.

onFulfilled or onRejected must not be called until the execution context stack contains only platform code.

另请参见注释1 :

此处的平台代码"表示引擎,环境和Promise实现代码.在实践中,此要求可确保在事件循环回合之后调用onFulfilled和onRejected异步执行,然后使用新的堆栈进行调用.可以使用宏任务"机制(例如setTimeout或setImmediate)或微任务"机制(例如MutationObserver或process.nextTick)来实现.由于promise实现被视为平台代码,因此它本身可能包含一个任务调度队列或蹦床",在其中调用处理程序.

Here "platform code" means engine, environment, and promise implementation code. In practice, this requirement ensures that onFulfilled and onRejected execute asynchronously, after the event loop turn in which then is called, and with a fresh stack. This can be implemented with either a "macro-task" mechanism such as setTimeout or setImmediate, or with a "micro-task" mechanism such as MutationObserver or process.nextTick. Since the promise implementation is considered platform code, it may itself contain a task-scheduling queue or "trampoline" in which the handlers are called.

因此,这实际上是规范要求的.

So this is actually mandated by the spec.

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

It was discussed extensively to make sure that this requirement is clear - see:

  • https://github.com/promises-aplus/promises-spec/pull/70
  • https://github.com/promises-aplus/promises-spec/pull/104
  • https://github.com/promises-aplus/promises-spec/issues/100
  • https://github.com/promises-aplus/promises-spec/issues/139
  • https://github.com/promises-aplus/promises-spec/issues/229

这篇关于节点; Q承诺延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆