Loading... ### 图解同步以及异步 <div class="preview"> <div class="post-inser post box-shadow-wrap-normal"> <a href="https://www.wumao.org/659.html" target="_blank" class="post_inser_a no-external-link"> <div class="inner-image bg" style="background-image: url(https://www.wumao.org/usr/themes/handsome/assets/img/sj/1.jpg);background-size: cover;"></div> <div class="inner-content" > <p class="inser-title">js中的同步和异步的理解</p> <div class="inster-summary text-muted"> 一个应用程序就是一个进程(当然有时候一个应用程序有多个进程),一个进程里面又分为很多个线程,线程是是程序执行流的最... </div> </div> </a> <!-- .inner-content #####--> </div> <!-- .post-inser ####--> </div> 去年写了一个同步和异步之前的差异其中说了事件循环,但是有点模糊,这里再记载一下 ![stack][1] 从图中所知,js运行代码时会把任务放到main stack中,如图所示stack的特点是先进后出,后进先出 但是遇到异步代码会怎么样 ![event loop][2] 如图所示,js引擎会优先执行同步代码,遇到异步代码会首先把异步代码通过web api挂载起来,他会把里面的代码加到一个队列中,队列的特性是先进先出后进后出,等异步代码执行完毕,再把里面的同步代码放入到main stack中运行 ### 宏任务与微任务 当遇到异步任务时被加入到事件循环时,同时分为宏任务(macrotask)以及微任务(microtask)这两读音好像啊。 #### 其中宏任务有 - script全部代码 - setTimeout - setInterval - setImmediate(浏览器暂时不支持,只有IE10支持,具体可见MDN) - I/O操作 - UI Rendering #### 微任务有 - Promise.then - MutaionObserver - process.nextTick (Node.js) - Object.observe(废弃) 当js挂起异步任务的时候,其中有两个队列,一个是宏任务队列一个是微任务队列,其中是怎么运行的呢 - 选择当前要执行的任务队列,选择任务队列中最先进入的任务,如果任务队列为空即null,则执行跳转到微任务(MicroTask)的执行步骤。 - 将事件循环中的任务设置为已选择任务 - 执行任务 - 将事件循环中当前运行任务设置为null - 将已经运行完成的任务从任务队列中删除 - microtasks步骤:进入microtask检查点 - 更新界面渲染 - 返回第一步 ![][3] 运行流程如下,一句话总结来说:微任务权重比宏任务要高在队列中优先执行 ### 练习题 ``` async function async1() { console.log('async1 start'); await async2(); console.log('async1 end'); } 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'); ``` 首先执行同步代码```console.log('script start'); ``` 然后挂起一个宏任务``` console.log('setTimeout'); ``` 再执行同步代码``` console.log('async1 start'); ``` 继续执行async2的同步代码```console.log('async2');``` 挂起微任务```console.log('async1 end');``` 下面的new Promise执行同步代码```console.log('promise1'); ``` .then挂起微任务```console.log('promise2'); ``` 执行同步代码```console.log('script end'); ``` 所以执行结果是 ``` script start async1 start async2 promise1 script end async1 end promise2 setTimeout ``` 下面还有两题同理 ``` setTimeout(() => { console.log('A'); // 4 }, 0); var obj = { func: function () { setTimeout(function () { console.log('B'); //5 }, 0); return new Promise(function (resolve) { console.log('C'); // 1 resolve(); }); }, }; obj.func().then(function () { console.log('D'); // 3 }); console.log('E'); // 2 ``` ``` let p = new Promise(resolve => { resolve(1); Promise.resolve().then(() => console.log(2)); console.log(4); }).then(t => console.log(t)); console.log(3); ``` [1]: https://www.wumao.org/usr/uploads/2020/04/2112745643.gif [2]: https://www.wumao.org/usr/uploads/2020/04/2322810425.gif [3]: https://www.wumao.org/usr/uploads/2020/04/1576711586.png Last modification:April 16th, 2020 at 05:00 pm © 允许规范转载 Support If you think my article is useful to you, please feel free to appreciate ×Close Appreciate the author Sweeping payments Pay by AliPay Pay by WeChat