异步机制
JavaScript的异步机制是事件轮询。
- Js引擎发起的任务是微任务
- 宿主(浏览器)发起的任务是宏任务
下面这张图大概阐述了哪些是宏任务哪些是微任务,都是我们比较常用的。比如,promise是微任务,setTimeOut是宏任务。
- 所有同步任务都先在操作系统主线程上先执行
- 主线程执行一个宏任务后,先访问微任务队列
- 微任务队列空了再访问下一个宏任务
- 下一个宏任务被放到主线程上执行,回到第二点
所以,宏任务需要多次事件循环才能执行完,微任务是一次性执行完的
有一些需要注意的:
- resolve或者reject改变状态的时候,才会将then或者catch的回调加入微任务队列
- promise回调(不是then或者catch回调)是同步的,resolve函数的调用也是同步的,可以继续执行resolve之后的代码。
- 链式调用,只有当上个微任务执行之后才会将下一个链式调用加入微任务队列。所以如果有多个链式调用的情况就要小心了。
- await虽然是同步代码,会执行。但是await后面的代码会被阻塞,相当于await后面的代码被加入到一个Promise.then()中(相当于此时新建了一个微任务了)
- async定义function的时候不会被执行,相当于普通函数被定义了。只用调用这个函数才会执行。
async function async1() { console.log("async1 start"); await async2(); console.log("async1 end"); } async function async2() { console.log("async2"); } async1(); console.log('start') // 'async1 start' // 'async2' // 'start' // 'async1 end'
Promise
推荐一篇好文章:一口气刷完45道promise面试题
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)
关于状态:
- Promise的回调是同步的,而then的回调是异步的
- Promise不返回真实结果,而返回一个承诺,由then来执行回调。reslove、reject来改变状态。
- Promise的状态一旦发生改变就无法更改(resolve或者reject)
- 如