JS执行机制
-
同步异步
同步:按照顺序依次执行
异步:先执行一部分,等拿到结果或等到相应时间后执行后续代码(计时器,ajax,读取文件)
同步程序执行完之后执行异步程序
-
单线程
js是单线程的,一个任务完成后才能执行另一个任务
for(let i=0; i<2000; i++){ console.log(1) } setTimeout(()=>{console.log(2)}, 0) setTimeout(()=>{console.log(3)}, 0) setTimeout(()=>{console.log(4)}, 0) console.log(5) //先输出两千个1之后再输出5,2,3,4
-
执行顺序
-
同步
-
nextTick(异步之前执行)
-
异步
-
setImmediate(当前事件循环结束执行)
事件循环会一直在任务队列里找任务执行
setImmediate(() => { console.log(1) }) process.nextTick(() => { console.log(2) }) console.log(3) setTimeout(() => { console.log(4) }, 0) //当等待时间结束后再把 log(5) 添加到任务队列 setTimeout(() => { console.log(5) }, 1000) setTimeout(() => { console.log(6) }, 0) console.log(7) //结果:3,7,2,4,6,1,5
-
4.宏任务与微任务
在 JS 中,异步任务又被分为宏任务与微任务
一、 执行script中代码,有一些是同步任务,有一些是异步任务,遇同步任务立即执行,遇异步任务分别丢入对应任务队列中(宏任务放进宏队列中,微任务放入微队列中),全局Script代码执行完毕后,同步任务执行完毕,栈Stack会清空
二、接着执行任务队列中的微任务,微任务执行结束后再执行宏任务
宏任务:整体script代码,计时器(setTimeout、setInterval),ajax,读取文件
微任务:promise.then
执行顺序:
-
同步程序
-
process.nextTick(node独有)
-
微任务
-
宏任务
-
setImmediate(node独有)
console.log(1) async function async1() { await async2() console.log(2) } async function async2() { console.log(3) } async1() setTimeout(() => { console.log(4) }, 0) new Promise(resolve => { console.log(5) resolve() }).then(function() { console.log(6) }).then(function() { console.log(7) }) console.log(8) // 输出:1,3,5,8,2,6,7,4
console.log(1); setTimeout(function () { console.log(2); new Promise(function (resolve) { console.log(3); resolve(); }).then(function () { console.log(4); }); }); new Promise(function (resolve) { console.log(5); resolve(); }).then(function () { console.log(6); }); setTimeout(function () { console.log(7); new Promise(function (resolve) { console.log(8); resolve(); }).then(function () { console.log(9); }); }); // 输出:1 5 6 2 3 4 7 8 9
讲解:
1.首先,先按照顺序执行同步任务:1 5
2.同步任务执行完成了,开始执行异步任务,异步任务先微任务后宏任务,所以先执行promise.then中的6。微任务执行完毕,开始宏任务,第一个setTimeout中输出2 3 4
4.接着执行第二个setTimeout中输出7 8 9