We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
填坑。。
这两个方法是BOM提供的功能,均接收两个参数:
setTimeout(fn,ms) setInterval(fn,ms)
setTimeout(function () { //一些处理 setTimeout(arguments.callee, interval);//调用自己 }, interval)
首先需要清楚的事情:
(1)task(macrotask)的种类
(2)microtask(一个EL中只有一个microtask队列,通常下面几种任务被认为是microtask)
promise(promise的then和catch才是microtask,本身其内部的代码并不是)
MutationObserver
process.nextTick(nodejs环境中)
循环过程: 任意选择一个task(宏任务)队列=>选择最早进入的一个task执行=>设为currently running task=>运行该task=>currently running task 置为 null=>当前task出队=>Microtasks=>更新渲染=>如果这是一个worker event loop,但是task队列中没有任务,并且WorkerGlobalScope对象的closing标识为true,则销毁EL,中止这些步骤,然后 run a worker(没太明白。。。)
简短版循环过程:
一个宏任务,所有微任务(,更新渲染),一个宏任务,所有微任务(,更新渲染)......
Node中的EL由 libuv库 实现,它为 Node.js 提供了跨平台,线程池,事件池,异步 I/O 等能力。
图中每个阶段都有自己的回调函数队列,进入该阶段执行队列中所有的回调(或者最大限制数量的回调),然后清理nextTickQueue/microtasks,进入下一阶段。
setTimeout() setInterval()
除了timers、check、close
Queue setImmediate()
socket.on('close', ...)
timers: poll阶段来控制什么时候执行timers callbacks I/O : 处理异步事件的回调,比如网络I/O,比如文件读取I/O。当这些I/O动作都结束的时候,在这个阶段会触发它们的回调。 poll: (迷。。。。)获取新的I/O事件。这里有一个最大事件数的限制。由于其它各个阶段的操作都有可能导致新的事件发生,并使得内核向poll queue中添加事件,所以在poll阶段处理事件的同时可能还会有新的事件产生,最终,长时间的调用回调函数将会导致定时器过期,所以在poll阶段与定时器会有"合作"。
1、有timer=>poll进入空闲状态=>EL检查timers=>有timer到期=>回到 timers 阶段执行timers queue 2、无timer=>poll queue不为空=>执行队列中的callback,直到为空或者达到上限 =========> poll queue空=>有setImmediate()(check)=>结束poll阶段进入check阶段 =====================>没有setImmediate()(check)=>event loop将阻塞在poll等待callbacks加入
check: poll队列闲置下来或者是代码被setImmediate调度,EL会马上进入check phase close: 关闭I/O的动作,比如文件描述符的关闭,连接断开等;如果socket突然中断
同步任务=>同步任务中的异步操作发出异步请求=>执行process.nextTick() 开始循环
优先级: nextTick > microtask setTimeout/setInterval > setImmediate 在同一个I/O cycle中,immediate 总比 timeout 更早被调度 关于process.nextTick: Node.js 最终选择的实现方法是将 microtask queue 的任务通过一个 runMicrotasks 对象暴露给上游,然后通过 nextTick 方法把它们推进了 nextTickQueue,也就是说最终 microtask queue 的任务变成了 nextTickQueue 的任务,所以我们用 promise.then 和 process.nextTick 可以实现相同的效果。
浏览器和NodeJS中不同的Event Loop setTimeout说事件循环 JavaScript定时器原理及高级使用
The text was updated successfully, but these errors were encountered:
期待总结哦
Sorry, something went wrong.
No branches or pull requests
填坑。。
1、先从setTimeout和setInterval说起
这两个方法是BOM提供的功能,均接收两个参数:
2、浏览器中的EL
首先需要清楚的事情:
(1)task(macrotask)的种类
(2)microtask(一个EL中只有一个microtask队列,通常下面几种任务被认为是microtask)
promise(promise的then和catch才是microtask,本身其内部的代码并不是)
MutationObserver
process.nextTick(nodejs环境中)
循环过程:
任意选择一个task(宏任务)队列=>选择最早进入的一个task执行=>设为currently running task=>运行该task=>currently running task 置为 null=>当前task出队=>Microtasks=>更新渲染=>如果这是一个worker event loop,但是task队列中没有任务,并且WorkerGlobalScope对象的closing标识为true,则销毁EL,中止这些步骤,然后 run a worker(没太明白。。。)
简短版循环过程:
3、NodeJS中的EL
图中每个阶段都有自己的回调函数队列,进入该阶段执行队列中所有的回调(或者最大限制数量的回调),然后清理nextTickQueue/microtasks,进入下一阶段。
setTimeout() setInterval()
设定的回调函数除了timers、check、close
阶段的回调Queue setImmediate()
设定的回调函数socket.on('close', ...)
timers: poll阶段来控制什么时候执行timers callbacks
I/O : 处理异步事件的回调,比如网络I/O,比如文件读取I/O。当这些I/O动作都结束的时候,在这个阶段会触发它们的回调。
poll: (迷。。。。)获取新的I/O事件。这里有一个最大事件数的限制。由于其它各个阶段的操作都有可能导致新的事件发生,并使得内核向poll queue中添加事件,所以在poll阶段处理事件的同时可能还会有新的事件产生,最终,长时间的调用回调函数将会导致定时器过期,所以在poll阶段与定时器会有"合作"。
1、有timer=>poll进入空闲状态=>EL检查timers=>有timer到期=>回到 timers 阶段执行timers queue
2、无timer=>poll queue不为空=>执行队列中的callback,直到为空或者达到上限
=========> poll queue空=>有setImmediate()(check)=>结束poll阶段进入check阶段
=====================>没有setImmediate()(check)=>event loop将阻塞在poll等待callbacks加入
check: poll队列闲置下来或者是代码被setImmediate调度,EL会马上进入check phase
close: 关闭I/O的动作,比如文件描述符的关闭,连接断开等;如果socket突然中断
同步任务=>同步任务中的异步操作发出异步请求=>执行process.nextTick()
开始循环
优先级:
nextTick > microtask
setTimeout/setInterval > setImmediate 在同一个I/O cycle中,immediate 总比 timeout 更早被调度
关于process.nextTick:
Node.js 最终选择的实现方法是将 microtask queue 的任务通过一个 runMicrotasks 对象暴露给上游,然后通过 nextTick 方法把它们推进了 nextTickQueue,也就是说最终 microtask queue 的任务变成了 nextTickQueue 的任务,所以我们用 promise.then 和 process.nextTick 可以实现相同的效果。
参考
浏览器和NodeJS中不同的Event Loop
setTimeout说事件循环
JavaScript定时器原理及高级使用
The text was updated successfully, but these errors were encountered: