繁体   English   中英

浏览器和节点中的EventLoop有什么区别?

[英]What's the difference between EventLoop in browsers and node?

Promise.resolve().then(() => {
  console.log('promise2')
  setTimeout(() => console.log('setTimeout2'))
})
setTimeout(() => {
  console.log('setTimeout1')
  Promise.resolve().then(() => console.log('promise1'))
})

在浏览器中运行代码的结果:

promise2 -> setTimeout1 -> promise1 -> setTimeout2

但在节点

promise2 -> setTimeout1 -> setTimeout2 ->promise1 

首先,讨论的第三条语句将计时器(t)和已实现的promise(f)回调的匿名函数标识为t1t2f1f2

Promise.resolve().then(() => { // f2
  console.log('promise2')
  setTimeout(() => console.log('setTimeout2') /* t2 */)
})  // statement 1

setTimeout(() => {  // t1
  console.log('setTimeout1')
  Promise.resolve().then(() => console.log('promise1'/* f1 */) // statement 3
}  // statement 2

语句1将1 f2放置在Promise作业队列(PJQ)中,假设Promise.resolve的参数不是Promise或thenable时,它会同步返回已实现的Promise。 then在已实现的Promise上进行调用,将在调用过程中将已实现的处理程序的执行分派给PJQ,稍后在处理Promise作业队列时执行。

语句2将t1放在计时器回调队列中。


1执行后,promise处理程序将由执行者代码监视thencatch返回的promise。


在浏览器中处理队列,将优先级设置为Promise作业队列:

PJQ:     <empty>
Timers:  t1, t2

调用f2,记录“ promise2”,将t2添加到计时器队列中

PJQ:    f1
Timers: t2

调用t1,记录“ setTimeout1”,执行语句3,将f1添加到Promise作业队列中。

PJQ:    <empty>
timers: t2

呼叫f1,记录“ promise1”

 PJQ: <empty> timers: t2 

调用t2,记录“ setTimeout2”。

因此,当承诺作业队列的优先级高于计时器回调时,日志将显示为“ promise2”,“ setTimeout1”,“ promise1”,“ setTimeout2”。


以创建顺序处理计时器和承诺作业的队列,这些队列没有优先级:

f2,t1

记录“ promise2”,添加t2

t1,t2

记录“ setTimeout1”,添加f1

t2,f1

记录“ setTimeout2”

f1

记录“ promise1”

因此,对于节点,日志的优先级相同,分别是“ promise2”,“ setTImeout1”,“ setTimeout2”,“ promise1”。


TLDR;

浏览器优先于承诺响应工作,而不是计时器回调。 节点与为计时器和承诺作业赋予相同的优先级是一致的,但请查阅文档。

编码承诺体系结构是一个veryBadIdea (tm) ,它依赖于计时器回调和承诺作业队列执行的优先级。 这在主机环境(浏览器与节点)之间以及在本地Promise库和JavaScript Promise库之间可能有所不同,这些Promise库和JavaScript Promise库已被使用或作为旧浏览器中Promise的polyfill包括在内。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM