Win*_*ing 5 javascript promise ecmascript-6 es6-promise
我只是想提高我对 JavaScript Promises 工作原理的理解。我创造了以下情况:
LOG 'FOO'
RUN CALLBACK LOGGING 'CALLBACK'
LOG 'BAR'
Run Code Online (Sandbox Code Playgroud)
期望所有功能立即完成(我的意思是它们不会花费过多/未知的时间来完成,您将使用异步操作来完成)以便上述操作顺序将按该顺序发生。
您可以通过以下方式编写:
function foo(cb) {
// LOG 'FOO'
console.log('foo');
// RUN CALLBACK
cb();
}
function callback() {
// LOG 'CALLBACK'
console.log('callback');
}
foo(callback);
console.log('bar');
Run Code Online (Sandbox Code Playgroud)
这会根据我在开始时指定的情况产生预期的输出。
> foo
> callback
> bar
Run Code Online (Sandbox Code Playgroud)
您也可以通过以下方式编写它:
function foo() {
return new Promise((resolve) => {
// LOG 'FOO'
console.log('foo');
return resolve(null);
});
}
function callback() {
// LOG 'CALLBACK'
console.log('callback');
}
foo().then(callback);
// LOG 'BAR'
console.log('bar');
Run Code Online (Sandbox Code Playgroud)
这种情况会产生以下结果:
> foo
> bar
> callback
Run Code Online (Sandbox Code Playgroud)
这是我不清楚我期待foo已完成,立即使callback运行和日志'callback'之前bar日志'bar'
相关规格在这里:
onFulfilled或者onRejected在执行上下文堆栈仅包含平台代码之前不得调用。[3.1]。
并注意 3.1(强调我的):
这里的“平台代码”是指引擎、环境和promise实现代码。在实践中,这个要求确保
onFulfilled和onRejected异步执行,在调用 then 的事件循环之后,并使用新的堆栈。这可以通过“宏任务”机制(例如setTimeout或setImmediate)或“微任务”机制(例如MutationObserver或 )来实现process.nextTick。由于promise实现被认为是平台代码,它本身可能包含一个任务调度队列或“trampoline”,在其中调用处理程序。
的ECMAScript 6.0(基于承诺/ A +)是有点难以摘录干净,但then做出决议如在章节25.4.5.3.1:
否则,如果promise的 [[PromiseState]] 内部槽的值为
"fulfilled",一种。让value为promise的 [[PromiseResult]] 内部槽的值。
湾 执行 EnqueueJob(
"PromiseJobs", PromiseReactionJob, «?fulfillReaction, value» )。否则,如果 promise 的 [[PromiseState]] 内部槽的值为
"rejected",一种。让reason是promise的 [[PromiseResult]] 内部槽的值。
湾 执行 EnqueueJob(
"PromiseJobs", PromiseReactionJob, «?rejectReaction, reason» )。
重要的 EnqueueJob 操作在第 8.4 节(“作业和作业队列”)中定义,在其序言中对此进行了说明(粗体是我的):
只有当没有正在运行的执行上下文且执行上下文堆栈为空时,才能启动 Job 的执行。[...] 一旦 Job 开始执行,Job 总是执行到完成。在当前运行的作业完成之前,不能启动其他作业。
在实践中,这可以让您做出一些简单且一致的陈述:
then或catch(等)始终异步运行,而不是同步运行。then或catch处理程序。这也意味着递归 Promise 执行不会像普通函数调用那样冒堆栈溢出的风险,尽管如果您在病态情况下不小心使用递归闭包,您仍然可能会耗尽堆空间。then或catch处理程序中排队的耗时操作永远不会阻塞当前线程,即使 Promise 已经结算,因此您可以将多个异步操作排队,而无需担心订单或承诺状态。try一个thenor之外的封闭块catch,即使在调用then已经解决的 Promise 时也是如此,因此平台是否应该处理抛出的异常没有歧义。| 归档时间: |
|
| 查看次数: |
1365 次 |
| 最近记录: |