【发布时间】:2014-06-20 07:16:15
【问题描述】:
考虑以下 JavaScript 代码:
var promise = new Promise();
setTimeout(function() {
promise.resolve();
}, 10);
function foo() { }
promise.then(foo);
在我见过的 promise 实现中,promise.resolve() 会简单地设置一些属性来指示 promise 已解决,并且 foo() 将在事件循环中稍后被调用,但它看起来像 promise.resolve( ) 将有足够的信息来立即调用任何延迟函数,例如 foo()。
事件循环方法似乎会增加复杂性并降低性能,那么为什么要使用它呢?
虽然我对 Promise 的大部分使用是与 JavaScript 一起使用的,但我提出问题的部分原因是在 C++ 游戏等性能非常密集的情况下实现 Promise,在这种情况下,我想知道是否可以利用承诺没有事件循环的开销。
【问题讨论】:
-
如果你想立即解决一个承诺,你只需调用
promise.resolve(),它会在那个时候调用任何注册的解析处理程序。如果您希望自己的事件循环在承诺解决之前展开,那么您可以使用setTimeout(function() {promise.resolve()}, 10);。但是,这取决于您希望.resolve()的行为方式。不需要使用setTimeout()。 -
是的,我明白这一点。我想了解的是,使用 setTimeout 时,10 毫秒后 foo() 不会立即被调用,而是将分辨率放在队列中,而 foo() 会在一段时间后执行。
-
哪个承诺实现可以做到这一点?有许多不同的实现,所以很难在不参考具体实现的情况下提出这样的问题。据我所知,没有规范说在延迟之后才应该调用解析回调。
-
我很想知道哪些承诺实现不这样做。 Promise/A+ spec 中建议使用延迟事件循环,这似乎是假定的方法。如果你需要一个例子,我最熟悉when.js,它使用了这样一个循环。
-
所以,您问为什么 Promises/A+ 规范的第 2.2.4 节规定:
Fulfilled or onRejected must not be called until the execution context stack contains only platform code. [[3.1](#notes)].?我们可以猜测,但您需要一个实际参与规范制作的人来解释他们当时的推理。仅供参考,这种架构中的一些可能假设了一种垃圾收集语言,在该语言中,在堆栈展开后很容易挂起对事物的引用。这在 C++ 中并不容易,因为对于 asyncresolve(),内存管理要困难得多。
标签: javascript c++ performance promise