异步
如果函数是异步的,发出调用之后,马上返回,但是不会马上返回预期结果。
调用者不必主动等待,当被调用者拿到结果之后会通过回调函数主动通知调用者。
浏览器内核是多线程的,通常由几个常驻线程
渲染引擎线程:负责页面的渲染
JS引擎线程:负责 JS 解析和执行
定时触发器线程:处理定时事件,比如setTimeout、setInterval
事件触发线程:处理DOM事件
异步http请求线程:处理http请求
渲染线程和 JS 引擎线程不能同时进行。渲染线程在执行任务的时候,JS 引擎线程会被挂起。
因为 JS 可以操作 DOM,若在渲染中 JS 处理了 DOM,浏览器可能不知所措了。
虽然 JavaScript 是单线程的,可是浏览器内部不是单线程的,一些 I/O 操作、定时器计时
和事件监听(click,keydown…)等都是由浏览器提供的其他线程来完成的。
假设异步任务的回调是在操作 DOM,但是页面渲染也是一个任务,如果把 DOM 渲染的任务排到异步任务的队尾,那么页面同样会出现瘫痪,所以 JS 就规定一些可以插队完成的任务,这类任务名称为微任务,如DOM渲染、promise.then…
宏任务:HTML解析、鼠标事件、键盘事件、网络请求、执行主线程JS代码和定时器,注 new Promise(xxx)中的xxx是同步代码。
微任务:promise.then、dom渲染、async、process.nextTick
<script>
console.log(1);
setTimeout(() => {
console.log(4)
}, 2000);
setTimeout(() => {
console.log(3);
}, 1000);
console.log(2);
// 1 2 3 4
</script>
<script>
console.log(1);
new Promise((resolve, reject) => {
console.log("请求即将进行");
setTimeout(() => {
console.log("已请求到数据");
resolve();
}, 1000);
}).then(() => {
console.log(3);
});
setTimeout(() => {
console.log(4);
}, 2000);
console.log(2);
// 1 请求即将执行 2 已请求到数据 3 4
</script>
<script>
console.log(1);
new Promise((resolve, reject) => {
console.log("请求即将进行");
setTimeout(() => {
console.log("已请求到数据");
resolve();
}, 2000)
}).then(() => {
console.log(3);
});
setTimeout(() => {
console.log(4);
}, 1000);
console.log(2);
// 1 请求即将进行 2 4 已请求到数据 3
// 两个 setTimeout 可以看成是 ajax 请求
</script>
参考:https://blog.csdn.net/titoni_yunruohan/article/details/110187508