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
众所周知,Javascript是单线程的脚本语言,也就是说,同一个时间只能做一件事。它的主要用途是与用户互动,以及操作DOM。由于它的用途决定了它只能是单线程的。
举个例子,假定JavaScript同时有两个线程a, b,这两个线程都对一个DOM进行不同的操作,a线程添加内容,b线程删除内容,那浏览器怎么判断呢?即便后来HTML5提出Web Worker来允许Javascript创建多个线程,但本质上还是主线程控制子线程,只是分担主线程的一部分计算任务,并没有改变JavaScript单线程的本质。
同步:在执行某个函数后,能够在执行后直接得到返回结果的操作。
异步:在执行某个函数后,不能够在执行后直接得到返回结果的,而需要通过其他手段才能得到结果的操作。
同步就是串行,异步就是并行。
基本数据类型(按值访问) Number, String, Null, Undefined, Boolean, Symbol(ES6)
引用类型(引用地址访问)
Object, Array, Function
栈stack:自动分配的内存空间,它由系统自动释放,空间小,运行效率高。
一般基本数据类型存放在栈区,栈遵循后进先出的原则。
堆heap:动态分配的内存,自定义大小,用户主动自动释放,空间大,运行效率低。
一般引用数据类型存放在堆区。
JavaScript并发模型基于“事件循环”, 浏览器提供运行时环境来执行我们的JavaScript代码, 浏览器主要包括 调用堆栈 ,事件循环 ,任务队列 和 Web API 。像setTimeout,setInterval和Promise这样的全局函数不是JavaScript的一部分,而是Web API的一部分。JavaScript环境的可视化表示如下所示:
JS调用堆栈是后进先出(LIFO)。引擎一次从堆栈中获取一个函数,并从上到下依次运行代码。每次遇到一些异步代码(如setTimeout)时,它都会将其交给Web API(箭头1)。因此,每当触发事件时,callback都会被发送到任务队列(箭头2)。Event Loop不断监视任务队列,并按照排队顺序一次处理一个callback。每当调用堆栈为空时,循环检索回调并将其放入堆栈(箭头3)进行处理。请记住,如果调用堆栈不为空,则事件循环不会将任何callbacks推送到堆栈。
事件循环具有一个或多个任务队列。 任务队列是一个有序的任务列表,一个任务队列便是一系列有序任务(task)的集合;每个任务都有一个任务源(task source),源自同一个任务源的 task 必须放到同一个任务队列,从不同源来的则被添加到不同队列。
任务队列是先进先出。
JavaScript在主线程执行任务会形成一个执行栈。
JavaScript在执行完执行栈的内容后,会读取任务队列中的任务加入执行栈并依次执行。
在JavaScript中异步任务中分为两种任务,宏任务(macro)task和微任务(microtask),那么我们是如何区分的这两种任务的呢?
microtask
宏任务在单个循环周期中一次一个地推入堆栈,但是微任务队列总是在执行返回到event loop(包括任何额外排队的项)之前清空。
event loop
宏任务(macrotask):
macrotask
script(全局任务)、setTimeout、setInterval、UI 渲染、 I/O、postMessage、 MessageChannel、setImmediate(Node.js 环境)
微任务(microtask):
Promise、 MutaionObserver、Object.observer,process.nextTick(Node.js环境)
它又是如何执行的呢?
在事件循环中,每进行一次循环操作称为 tick,每一次 tick 的任务处理的步骤如下: 1、执行栈选择宏任务(script)执行(有就执行,没有就下一步); 2、检查是否存在 Microtasks,如果存在则不停地执行,直至清空 Microtasks Queue; 3、render(每一次事件循环,浏览器都可能会去更新渲染); 4、重复上述步骤。
你还可以通过这个非常棒的可视化工具来理解调用堆栈
Tasks, microtasks, queues and schedules
So you think you know JavaScript?
JavaScript 运行机制详解:再谈Event Loop
tasks-microtasks-queues-and-schedules
event-loops
ask-queues
Eventloop不可怕,可怕的是遇上Promise
The text was updated successfully, but these errors were encountered:
JavaScript
No branches or pull requests
众所周知,Javascript是单线程的脚本语言,也就是说,同一个时间只能做一件事。它的主要用途是与用户互动,以及操作DOM。由于它的用途决定了它只能是单线程的。
举个例子,假定JavaScript同时有两个线程a, b,这两个线程都对一个DOM进行不同的操作,a线程添加内容,b线程删除内容,那浏览器怎么判断呢?即便后来HTML5提出Web Worker来允许Javascript创建多个线程,但本质上还是主线程控制子线程,只是分担主线程的一部分计算任务,并没有改变JavaScript单线程的本质。
同步和异步
同步:在执行某个函数后,能够在执行后直接得到返回结果的操作。
异步:在执行某个函数后,不能够在执行后直接得到返回结果的,而需要通过其他手段才能得到结果的操作。
同步就是串行,异步就是并行。
JavaScript变量类型
基本数据类型(按值访问)
Number, String, Null, Undefined, Boolean, Symbol(ES6)
引用类型(引用地址访问)
Object, Array, Function
栈内存(stack)与堆内存(heap)
栈stack:自动分配的内存空间,它由系统自动释放,空间小,运行效率高。
一般基本数据类型存放在栈区,栈遵循后进先出的原则。
堆heap:动态分配的内存,自定义大小,用户主动自动释放,空间大,运行效率低。
一般引用数据类型存放在堆区。
JavaScript并发模型基于“事件循环”, 浏览器提供运行时环境来执行我们的JavaScript代码, 浏览器主要包括 调用堆栈 ,事件循环 ,任务队列 和 Web API 。像setTimeout,setInterval和Promise这样的全局函数不是JavaScript的一部分,而是Web API的一部分。JavaScript环境的可视化表示如下所示:
JS调用堆栈是后进先出(LIFO)。引擎一次从堆栈中获取一个函数,并从上到下依次运行代码。每次遇到一些异步代码(如setTimeout)时,它都会将其交给Web API(箭头1)。因此,每当触发事件时,callback都会被发送到任务队列(箭头2)。Event Loop不断监视任务队列,并按照排队顺序一次处理一个callback。每当调用堆栈为空时,循环检索回调并将其放入堆栈(箭头3)进行处理。请记住,如果调用堆栈不为空,则事件循环不会将任何callbacks推送到堆栈。
任务队列(task queue)
事件循环具有一个或多个任务队列。 任务队列是一个有序的任务列表,一个任务队列便是一系列有序任务(task)的集合;每个任务都有一个任务源(task source),源自同一个任务源的 task 必须放到同一个任务队列,从不同源来的则被添加到不同队列。
任务队列是先进先出。
执行栈
JavaScript在主线程执行任务会形成一个执行栈。
JavaScript在执行完执行栈的内容后,会读取任务队列中的任务加入执行栈并依次执行。
宏任务和微任务
在JavaScript中异步任务中分为两种任务,宏任务(macro)task和微任务(
microtask
),那么我们是如何区分的这两种任务的呢?宏任务在单个循环周期中一次一个地推入堆栈,但是微任务队列总是在执行返回到
event loop
(包括任何额外排队的项)之前清空。宏任务(
macrotask
):微任务(
microtask
):它又是如何执行的呢?
在事件循环中,每进行一次循环操作称为 tick,每一次 tick 的任务处理的步骤如下:
1、执行栈选择宏任务(script)执行(有就执行,没有就下一步);
2、检查是否存在 Microtasks,如果存在则不停地执行,直至清空 Microtasks Queue;
3、render(每一次事件循环,浏览器都可能会去更新渲染);
4、重复上述步骤。
你还可以通过这个非常棒的可视化工具来理解调用堆栈
参考资料
Tasks, microtasks, queues and schedules
So you think you know JavaScript?
JavaScript 运行机制详解:再谈Event Loop
tasks-microtasks-queues-and-schedules
event-loops
ask-queues
Eventloop不可怕,可怕的是遇上Promise
The text was updated successfully, but these errors were encountered: