一、javascript 是一门单线程语言
二、js 运行机制
1、浏览器中
同步工作和异步工作
- 同步工作:比方页面骨架和页面元素的渲染
- 异步工作:比方加载图片音乐之类占用资源大耗时久的工作
* 看图 ==>
(1)同步的进入主线程,异步的进入 Event Table 并注册函数
(2)当指定的事件实现时,Event Table 会将这个函数移入工作队列
(3)主线程内的工作执行结束为空,会去工作队列读取对应的函数,进入主线程执行
(4)上述过程会一直反复,也就是常说的 Event Loop(事件循环)。
macro-task(宏工作) 和 micro-task(微工作)
macro-task(宏工作):整体代码 script、setTimeout、setInterval
micro-task(微工作):Promise、await、process.nextTick(nodejs)
* 碰到宏工作和微工作怎么执行呢
(1)执行整体代码 script(宏工作)
(2)执行所有的微工作
(3)再执行一个宏工作
(4)而后再执行所有的微工作,始终循环
鄙视题理解一下
console.log('1');
setTimeout(function() { // 宏 1
console.log('2');
process.nextTick(function() { // 微 1
console.log('3');
})
new Promise(function(resolve) {console.log('4');
resolve();}).then(function() { // 微 2
console.log('5')
})
})
process.nextTick(function() { // 微 3
console.log('6');
})
new Promise(function(resolve) {console.log('7');
resolve();}).then(function() { // 微 4
console.log('8')
})
setTimeout(function() { // 宏 2
console.log('9');
process.nextTick(function() { // 微 5
console.log('10');
})
new Promise(function(resolve) {console.log('11');
resolve();}).then(function() { // 微 6
console.log('12')
})
})
解析 ==============>
(1)执行整体代码(宏), 打印出 1 7
在这期间,挂起的异步工作有
宏 | 微 |
---|---|
宏 1 宏 2 | 微 3 微 4 |
(2)开始执行所有微工作(微 3、微 4),打印出6 8
, 此时工作队列残余
宏 | 微 |
---|---|
宏 1 宏 2 |
(3)执行一个宏工作(宏 1),打印出2 4
, 并且在这期间,又挂载了新的异步工作(微 1,微 2),因而工作队列残余
宏 | 微 |
---|---|
宏 2 | 微 1 微 2 |
(4)执行所有微工作(微 1,微 2),打印出3 5
,工作队列残余
宏 | 微 |
---|---|
宏 2 |
(5)执行一个宏工作(宏 2),打印出9 11
, 同时又挂载了新的异步工作(微 5, 微 6), 工作队列残余
宏 | 微 |
---|---|
微 5 微 6 |
(6)执行所有微工作(微 5, 微 6),打印出 10 12
因而,最初执行后果为 1 7 6 8 2 4 3 5 9 11 10 12
再看一道 =============================>
async function async1() {console.log('async1 start'); //=>2
await async2();
console.log('async1 end'); //=>6 // 微 1
}
async function async2() {console.log('async2'); //=>3
}
console.log('script start'); //=>1
setTimeout(function () { // 宏 1
console.log('setTimeout'); //=>9
}, 0);
async1();
new Promise(function (resolve) {console.log('promise1'); //=>4
resolve();}).then(function () { // 微 2
console.log('promise2'); //=>7
}).then(function () { // 微 3
console.log('promise3'); //=>8
});
console.log('script end'); //=>5
下面的数字代表执行程序,解析开始 ==========》
(1)执行整体代码(宏), 打印出 script start
async1 start
async2
promise1
script end
此时工作队列残余
宏 | 微 |
---|---|
宏 1 | 微 1 微 2 微 3 |
(2)顺次执行所有微工作(微 1 微 2 微 3),打印出 async1 end
promise2
promise3
此时工作队列残余
宏 | 微 |
---|---|
宏 1 |
(3)执行一个宏工作(宏 1),打印出setTimeout
因而执行后果 ==============>script start
async1 start
async2
promise1
script end
async1 end
promise2
promise3
setTimeout
参考链接
这一次,彻底弄懂 JavaScript 执行机制
一篇文章教会你 Event loop——浏览器和 Node