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
Event Loop即事件循环,是指浏览器或Node的一种解决JavaScript单线程运行时不会阻塞的一种机制,也就是我们经常使用异步的原理。
堆(Heap)
堆时一种数据结构,时利用完全二叉树维护的一组数据,堆分为两种,一种为最大堆,一种为最小堆,将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。 堆是线性数据结构,相当于一维数组,有唯一后继。
如最大堆
栈(Stack)
栈在计算机科学中是限定在表尾进行插入或删除操作的线性表。栈式一种数据结构,它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据。 栈是只能在某一端插入和删除的特殊线性表。
队列(Queue)
特殊之处在于它只允许在表的前端进行删除操作,而在表的后端进行插入操作,和栈一样,队列是一种操作受限制的线性表。 进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。 队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出。
在JavaScript中,任务被分为两种,一种宏任务(MacroTask),一种叫微任务(MicroTask).
MacroTask(宏任务)
MicroTask(微任务)
JavaScript有一个主线程和调用栈(执行栈),所有的任务都会被放到调用栈等待主线程执行。
JS调用栈
JS调用栈采用的时后进先出的规则,当函数执行的时候,会被添加到栈的顶部,当执行栈执行完成后,就会从栈顶移出,直到栈内被清空。
同步任务和异步任务
JavaScript单线程任务被分为同步任务和异步任务,同步任务会在调用栈中按照顺序等待主线程依次执行,异步任务会在异步任务有了结果后,将注册的回调函数放入任务队列中等待主线程空闲的时候(调用栈被清空),被读取到栈内等待主线程的执行。
任务队列是一种先进先出的一种数据结构。
事件循环的进程模型
执行进入microtask检查点时,用户代理会执行以下步骤
执行栈在执行完同步任务后,查看执行栈是否为空,如果执行栈为空,就会去检查微任务队列是否为空,如果为空的话,就执行宏任务,否则就一次性执行完所有微任务。 每次单个宏任务执行完后,检查微任务队列是否为空,如果不为空的话,会按照先入先出的规则全部执行完微任务后,设置微任务队列为null,然后再执行宏任务,如此循环。
console.log('script start'); setTimeout(function() { console.log('setTimeout'); }, 0); Promise.resolve().then(function() { console.log('promise1'); }).then(function() { console.log('promise2'); }); console.log('script end');
首先我们划分几个分类:
第一次执行:
Tasks:run script、 setTimeout callback Microtasks:Promise then JS stack: script Log: script start、script end。
执行同步代码,将宏任务(Tasks)和微任务(Microtasks)划分到各自队列中。
第二次执行:
Tasks:run script、 setTimeout callback Microtasks:Promise2 then JS stack: Promise2 callback Log: script start、script end、promise1、promise2
执行宏任务后,检测到微任务队列中不为空,执行Promise1,执行完成Promise1后,调用Promise2.then,放入微任务队列中,再执行Promise2.then。
第三次执行:
Tasks:setTimeout callback Microtasks: JS stack: setTimeout callback Log: script start、script end、promise1、promise2、setTimeout
当微任务队列中为空时,执行宏任务,执行setTimeout callback,打印日志。
第四次执行:
Tasks:setTimeout callback Microtasks: JS stack: Log: script start、script end、promise1、promise2、setTimeout
清空Tasks队列和JS stack。
Node中的Event Loop是基于libuv实现的,而libuv是Node的新跨平台抽象层,libuv使用异步,事件驱动的编程方式,核心是提供i/o的事件循环和异步回调。libuv的API包含有时间,非阻塞的网络,异步文件操作,子进程等。
Node的Event Loop一共分为6个阶段,每个细节具体如下:
The text was updated successfully, but these errors were encountered:
No branches or pull requests
前言
Event Loop即事件循环,是指浏览器或Node的一种解决JavaScript单线程运行时不会阻塞的一种机制,也就是我们经常使用异步的原理。
堆、栈、队列
堆(Heap)
堆时一种数据结构,时利用完全二叉树维护的一组数据,堆分为两种,一种为最大堆,一种为最小堆,将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。
堆是线性数据结构,相当于一维数组,有唯一后继。
如最大堆
栈(Stack)
栈在计算机科学中是限定在表尾进行插入或删除操作的线性表。栈式一种数据结构,它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据。
栈是只能在某一端插入和删除的特殊线性表。
队列(Queue)
特殊之处在于它只允许在表的前端进行删除操作,而在表的后端进行插入操作,和栈一样,队列是一种操作受限制的线性表。
进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出。
Event Loop
在JavaScript中,任务被分为两种,一种宏任务(MacroTask),一种叫微任务(MicroTask).
MacroTask(宏任务)
MicroTask(微任务)
浏览器中的Event Loop
JavaScript有一个主线程和调用栈(执行栈),所有的任务都会被放到调用栈等待主线程执行。
JS调用栈
JS调用栈采用的时后进先出的规则,当函数执行的时候,会被添加到栈的顶部,当执行栈执行完成后,就会从栈顶移出,直到栈内被清空。
同步任务和异步任务
JavaScript单线程任务被分为同步任务和异步任务,同步任务会在调用栈中按照顺序等待主线程依次执行,异步任务会在异步任务有了结果后,将注册的回调函数放入任务队列中等待主线程空闲的时候(调用栈被清空),被读取到栈内等待主线程的执行。
任务队列是一种先进先出的一种数据结构。
事件循环的进程模型
执行进入microtask检查点时,用户代理会执行以下步骤
执行栈在执行完同步任务后,查看执行栈是否为空,如果执行栈为空,就会去检查微任务队列是否为空,如果为空的话,就执行宏任务,否则就一次性执行完所有微任务。
每次单个宏任务执行完后,检查微任务队列是否为空,如果不为空的话,会按照先入先出的规则全部执行完微任务后,设置微任务队列为null,然后再执行宏任务,如此循环。
举个例子
首先我们划分几个分类:
第一次执行:
执行同步代码,将宏任务(Tasks)和微任务(Microtasks)划分到各自队列中。
第二次执行:
执行宏任务后,检测到微任务队列中不为空,执行Promise1,执行完成Promise1后,调用Promise2.then,放入微任务队列中,再执行Promise2.then。
第三次执行:
当微任务队列中为空时,执行宏任务,执行setTimeout callback,打印日志。
第四次执行:
清空Tasks队列和JS stack。
NodeJS的Event Loop
Node中的Event Loop是基于libuv实现的,而libuv是Node的新跨平台抽象层,libuv使用异步,事件驱动的编程方式,核心是提供i/o的事件循环和异步回调。libuv的API包含有时间,非阻塞的网络,异步文件操作,子进程等。
Node的Event Loop一共分为6个阶段,每个细节具体如下:
The text was updated successfully, but these errors were encountered: