我们经常会说
JavaScript是单线程
的,但是
JavaScript的线程应该有自己的容器进程
:
浏览器或者Node
浏览器是一个进程吗,它里面只有一个线程吗?
目前
多数的浏览器其实都是多进程
的,当我们
打开一个tab页面时就会开启一个新的进程
,这是为了
防止一个页
面卡死而造成所有页面无法响应
,整个浏览器需要强制退出
每个进程中又有很多的线程
,其中
包括执行JavaScript代码的线程
JavaScript的代码执行是在一个单独的线程中执行的
这就意味着JavaScript的代码,在
同一个时刻只能做一件事
如果
这件事是非常耗时
的,就意味着当前的线程就
会被阻塞
所以真正耗时的操作,实际上并不是由JavaScript线程在执行的
浏览器的每个进程是多线程的,那么
其他线程可以来完成这个耗时的操作
比如
网络请求、定时器
,我们只需要在特性的时候执行应该有的回调即可
但是事件循环中并非只维护着一个队列,事实上是有两个队列:
宏任务队列(macrotask queue)
:ajax、setTimeout、setInterval、DOM监听、UI Rendering等
微任务队列(microtask queue)
:Promise的then回调、 Mutation Observer API、queueMicrotask()等
也就是宏任务执行之前,必须保证微任务队列是空的
如果不为空,那么就优先执行微任务队列中的任务(回调)
setTimeout(function () {
console.log("setTimeout1");
new Promise(function (resolve) {
resolve();
}).then(function () {
new Promise(function (resolve) {
resolve();
}).then(function () {
console.log("then4");
});
console.log("then2");
});
});
new Promise(function (resolve) {
console.log("promise1");
resolve();
}).then(function () {
console.log("then1");
});
setTimeout(function () {
console.log("setTimeout2");
});
console.log(2);
queueMicrotask(() => {
console.log("queueMicrotask1")
});
new Promise(function (resolve) {
resolve();
}).then(function () {
console.log("then3");
});
// promise1
// 2
// then1
// queueMicrotask1
// then3
// setTimeout1
// then2
// then4
// setTimeout2
async function async1 () {
console.log('async1 start')
await async2();
console.log('async1 end') //等于then里面代码
}
async function async2 () {
console.log('async2')
}
console.log('script start')
setTimeout(function () {
console.log('setTimeout')
}, 0)
async1();
new Promise (function (resolve) {
console.log('promise1')
resolve();
}).then (function () {
console.log('promise2')
})
console.log('script end')
// script start
// async1 start
// async2
// promise1
// script end
// async1 end
// promise2
// setTimeout