JS单线程
概念:一个程序一个程序中只可以执行一个任务
为什么js是单线程
单线程是只指同一时间只能做一件事,js的单线程与它的用途有关,js的主要作用域用户互动以及操作DOM,这决定了它只能是单线程,否则会带来很复杂的同步问题;如:js同时有两个线程,一个线程在某个DOM节点添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?
为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变js单线程的本质。
单线程:所有任务可以分为两种,一种是同步任务,一种是异步任务。
JS事件循环
归类:遇到同步任务直接执行,遇到异步任务分类为宏任务(macro-task)和微任务(micro-task)。
宏任务:整体的Script setTimeout setInterval
微任务:Promise process.nextTick
setTimeout(function () { --------> 宏任务列表
console.log('2') 目前宏任务列表记为【2】
});
new Promise(function (resolve) {
// 这里是同步任务
console.log('3'); --------> 直接被执行
resolve(); 目前打印结果为:1、3
// then是一个微任务
}).then(function () { --------> setTimeout]被放进微任务列表
console.log('4')
setTimeout(function () {
console.log('5')
});
});
有微则微,无微则宏
如果微任务列表里面有任务 会执行完毕后在执行宏任务。
setTimeout(function () {
console.log('2') --------> 直接被执行
目前打印结果为:1、3、4、2
});
setTimeout(function () {
console.log('5') --------> 直接被执行
目前打印顺序为: 1、3、4、2、5、5
});
总结 + 实战
反复执行以上步骤 就是事件循环(event loop) 一定要分的清任务类型 (宏任务 和 微任务)
TIP: 为了容易辨别起名为p1(p开头 里面打印1)
process.nextTick(function() { --------> 被放微任务列表
console.log('1'); 微任务列表记为:【p1】
})
new Promise(function (resolve) {
console.log('2'); --------> 直接执行
resolve(); 目前打印顺序为:2
}).then(function () { --------> 整体的then被放进微任务列表[包含其中的setTimeout 4]
console.log('3'); 微任务列表记为:【p1 t34】
setTimeout(function () {
console.log('4')
});
});
多线程:一个程序中可以执行多个任务