异步

如果函数是异步的,发出调用之后,马上返回,但是不会马上返回预期结果。
调用者不必主动等待,当被调用者拿到结果之后会通过回调函数主动通知调用者。

浏览器内核是多线程的,通常由几个常驻线程
渲染引擎线程:负责页面的渲染
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

posted @ 2021-10-07 10:11  し7709  阅读(212)  评论(0编辑  收藏  举报