考虑以下代码:
function foo() {
console.log('foo');
new Promise(
function(resolve, reject) {
setTimeout(function() {
resolve('RESOLVING');
}, 5000);
}
)
.then(
function(value) {
console.log(value);
}
);
}
foo();
我正在尝试正确理解此处发生的情况:
new Promise
时,直接运行“ executer函数”,并且在调用setTimeout
时,计划将新条目添加到“事件队列”的操作(5秒钟后)< / li>
then
的调用被构造为在解析Promise
之后发生的对传递给函数的调用的操作(记录到控制台),该操作被添加到“作业队列”中< / li>
setTimeout
回调时(在事件循环的某个滴答处),将解析Promise
并基于第2点,向then
调用添加函数参数进入“作业队列”并随后执行。注意,我之所以说[一个“工作队列”],是因为我不确定某些事情;哪个“是工作队列?”。据我了解,“作业队列”链接到“事件队列”上的条目。那就是上面示例中的setTimeout
条目吗?
假设在添加setTimeout
的回调之前(和之后),没有其他事件添加到“事件队列”中,那么主代码(对foo的调用)的条目通常不会消失(到那时为止),因此setTimeout
的“作业队列”条目要链接到then
之外没有其他条目了?
答案 0 :(得分:2)
- 在执行
new Promise
时,直接运行“ executer函数”,并且在调用setTimeout
时,计划将新条目添加到“事件队列”的操作(5秒钟后)< / li>
是的。更具体地说,调用setTimeout
可以使用浏览器的计时器机制安排计时器;大约五秒钟后,计时器机制将一个作业添加到主作业队列中,该作业将调用您的回调。
- 由于对
then
的调用被构造为在解析Promise
之后发生的对传递给函数的调用的操作(记录到控制台),该操作被添加到“作业队列”中< / li>
对。 then
(带有单个参数)将一个实现处理程序添加到Promise(并创建它返回的另一个Promise)。当承诺解决后,将调用处理程序的作业添加到作业队列中(但这是一个不同的作业队列)。
- 在执行
setTimeout
回调时(在事件循环的某个滴答处),将解析Promise
并基于第2点,向then
调用添加函数参数进入“作业队列”并随后执行。
是的,但是工作队列不同。 :-)
主作业队列是事件处理程序和计时器回调之类的地方。主事件循环从队列中拾取一个作业,将其运行到完成,然后拾取下一个作业,依此类推,如果没有要运行的作业,则空转。
一旦作业运行完毕,就会运行另一个循环,该循环负责运行在该主要作业中计划的所有待处理的承诺作业。
在JavaScript规范中,主作业队列称为ScriptJobs,而promise回调作业队列为PromiseJobs。在ScriptJob的末尾,将在下一个ScriptJob之前执行已排队的所有PromiseJob。 (在HTML规范中,它们的名称是“任务”(或“宏任务”)和“微任务”。)
是的,这确实意味着,如果作业A和作业B都排队,然后作业A被接起并安排了承诺回调,则该承诺回调将在运行作业 之前运行,即使作业B首先(在主队列中)排队。
注意,我之所以说[一个“工作队列”],是因为我不确定某些事情;哪个“是工作队列?”
希望我已经在上面介绍了。基本上:
requestAnimationFrame
回调被排队到ScriptJobs队列(主要队列)中;它们是“宏任务”(或简称为“任务”)。按照我的理解,“作业队列”链接到“事件队列”上的条目。
这些只是同一事物的不同名称。 JavaScript规范使用术语“作业”和“作业队列”。 HTML规范使用“任务”,“任务队列”和“事件循环”。事件循环是从ScriptJobs队列中拾取作业的地方。
那将是上面示例中的
setTimeout
条目吗?
当计时器触发时,将在ScriptJobs队列中安排作业。
假定在添加
setTimeout
的回调之前(和之后)没有将其他事件添加到“事件队列”中,那么通常不会编写主代码的条目(对foo的调用) )到那时为止(运行完成),因此setTimeout
的“作业队列”条目将与then
一样没有其他条目可以链接?
基本上是。让我们开始吧:
foo
并对其进行了调用。foo
内,您进行console.log
,然后创建一个诺言。then
向诺言添加履行处理程序。console.log
更多探索: