[英]javascript promises, the event loop, and the job queue
请考虑以下代码:
function foo() {
console.log('foo');
new Promise(
function(resolve, reject) {
setTimeout(function() {
resolve('RESOLVING');
}, 5000);
}
)
.then(
function(value) {
console.log(value);
}
);
}
foo();
我试图理解这里发生的事情:
new Promise
,直接运行“执行器函数”,并且当调用setTimeout
时,将安排向“事件队列”添加新条目的操作(5秒后) then
添加到“作业队列”的操作,在Promise
解决后组织调用传递的函数(记录到控制台) setTimeout
回调时(在事件循环的某个刻度上), Promise
被解析,并且基于第2点, then
调用的函数参数被添加到“作业队列”并随后执行。 注意我说[一个“工作队列”],因为有一些我不确定的事情; 哪个“工作队列是吗?”。 我理解它的方式,“作业队列”链接到“事件队列”上的条目。 那么这就是上面例子中的setTimeout
条目吗? 假设在添加setTimeout
的回调之前(和之后)没有向“事件队列”添加其他事件,主代码的条目(对foo的调用)是否(通常)已经消失(运行完成)那个时候因为then
的“作业队列”条目没有其他条目而不是setTimeout
的链接到?
- 在执行
new Promise
,直接运行“执行器函数”,并且当调用setTimeout
时,将安排向“事件队列”添加新条目的操作(5秒后)
是。 更具体地说,调用setTimeout
使用浏览器的计时器机制来调度计时器; 大约五秒钟后,计时器机制将作业添加到主要作业队列中,该作业将调用您的回调。
- 因为调用
then
添加到“作业队列”的操作,在Promise
解决后组织调用传递的函数(记录到控制台)
对。 then
(使用单个参数)将一个履行处理程序添加到promise(并创建它返回的另一个promise)。 当promise解析时,调用处理程序的作业将添加到作业队列中(但它是一个不同的作业队列)。
- 当执行
setTimeout
回调时(在事件循环的某个刻度上),Promise
被解析,并且基于第2点,then
调用的函数参数被添加到“作业队列”并随后执行。
是的,但它不是同一个工作队列。 :-)
主要的作业队列就是事件处理程序和计时器回调等等。 主事件循环从队列中获取作业,将其运行至完成,然后选择下一个作业等,如果没有要运行的作业则空闲。
作业运行完成后,将运行另一个循环,该循环负责运行在该主作业期间计划的任何待处理的承诺作业。
在JavaScript规范中,主作业队列称为ScriptJobs,promise回调作业队列为PromiseJobs。 在ScriptJob结束时,所有已排队的PromiseJobs都会在下一个ScriptJob之前执行。 (在HTML规范中,它们的名称是“task”[或“macrotask”]和“microtask”。)
是的,这确实意味着如果作业A和作业B都排队,然后作业A被选中并安排一个承诺回调,则在作业B运行之前运行该承诺回调,即使作业B已排队(在主队列)首先。
注意我说[一个“工作队列”],因为有一些我不确定的事情; 哪个“工作队列呢?”
希望我已经涵盖了上述内容。 基本上:
requestAnimationFrame
回调排队到ScriptJobs队列(主要队列); 他们是“macrotasks”(或简称“任务”)。 我理解它的方式,“作业队列”链接到“事件队列”上的条目。
对于同样的事情,这些只是不同的名称。 JavaScript规范使用术语“作业”和“作业队列”。 HTML规范使用“任务”和“任务队列”和“事件循环”。 事件循环是从ScriptJobs队列中获取作业的。
那么这就是上面例子中的
setTimeout
条目吗?
当计时器触发时,作业将在ScriptJobs队列中进行调度。
假设在添加
setTimeout
的回调之前(和之后)没有向“事件队列”添加其他事件,主代码的条目(对foo的调用)是否(通常)已经消失(运行完成)那个时候因为then
的“作业队列”条目没有其他条目而不是setTimeout
的链接到?
基本上是的。 让我们把它搞定:
foo
并调用它。 foo
,您执行console.log
,然后创建一个promise。 then
在promise中添加一个履行处理程序。 console.log
更多探索:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.