1_p7iI_TBEVbCbrJneEaZZ8g@2x.png

宏任务和微任务

宏任务

消息队列中的等待被主线程执行的任务(通过事件循环系统来执行)

时间粒度较大,执行的时间间隔不能精准控制,对一些高实时性的需求不太符合

微任务

一个需要异步执行的函数,执行时机是在主函数执行结束之后、当前宏任务结束之前

f85b1b316f669316cef23c4714d4ce2d.jpg
338875c3ff58e389af86cf2acab5bd1c.jpg
34fb1a481b60708360b48ba04821f6db.jpg
267e549592913e25bdb6dfe716eeddc9.jpg

  • 通过异步操作解决了同步操作的性能问题
  • 通过微任务解决了实时性的问题

    Promise

    微信截图_20210228154635.png

    Promise 与微任务

    ```javascript function Bromise(executor) { var onResolve = null var onReject = null //模拟实现resolve和then,暂不支持rejcet this.then = function (onResolve, onReject) {
    1. onResolve_ = onResolve
    }; // 执行 then() 方法传进来的 onResolve() 函数 function resolve(value) {
    1. // 这里使用定时器延后执行 onResolve_ 函数
    2. // 避免在 Bromise.then 还没执行时就调用 onResolve_
    3. // 真实的 Promise 使用微任务来延迟 onResolve_ 执行
    4. setTimeout(()=>{
    5. onResolve_(value)
    6. },0)
    } executor(resolve, null); }

function executor(resolve, reject) { resolve(100) } //将Promise改成我们自己的Bromsie let demo = new Bromise(executor)

function onResolve(value){ console.log(value) } demo.then(onResolve)

// Promise 中的 resolve 函数其实就是执行了 then() 方法中传进来的 onResolve() 函数, // 但是用户调用 resolve() 往往是在构造函数的参数 execute() 函数中, // 而构造函数执行时,onResolve 函数还没被赋值。 // 因此在 resolve() 中执行 onResolve() 函数的代码需要用一个微任务来执行。

  1. <a name="nEqBe"></a>
  2. # async/await
  3. > 提供了在不阻塞主线程的情况下使用同步代码实现异步访问资源的能力
  4. ```javascript
  5. async function foo(){
  6. try{
  7. let response1 = await fetch('https://www.geekbang.org')
  8. console.log('response1')
  9. console.log(response1)
  10. let response2 = await fetch('https://www.geekbang.org/test')
  11. console.log('response2')
  12. console.log(response2)
  13. }catch(err) {
  14. console.error(err)
  15. }
  16. }
  17. foo()

背后技术构成

Promise(微任务) + 生成器应用(协程应用)

  1. async function foo() {
  2. console.log(1)
  3. let a = await 100
  4. console.log(a)
  5. console.log(2)
  6. }
  7. console.log(0)
  8. foo()
  9. console.log(3)

8dcd8cfa77d43d1fb928d8b001229b94.png

  • 一个线程可以拥有多个协程,但是在线程上同时只能执行一个协程

参考资料

  1. 浏览器工作原理与实践 —— 李兵
  2. 图解 Google V8