js是单线程的,一般情况下,只有上一段代码执行完毕后,才会执行下面的代码。
但是有时候需要向服务器请求数据,需要一段时间,为了不做到阻塞下面代码的运行,就有了同步任务和异步任务的区分。
js代码从上之下运行,同步任务和异步任务执行的环境不同,可以分为以下步骤:
- 同步任务会在主线程的执行栈内直接执行
- 当碰到请求事件比较长的异步代码,或者其他的异步函数,会将这些执任务,放到异步环境下进行执行注册
- 当异步任务注册完毕后,会将其回调函数放到任务队列中(像ajax成功获取会数据后执行的回调函数,计时器计时完毕执行的回调函数)
- 等待执行栈中的代码执行完后,会依次执行任务队列中注册的函数
- 在执行任务队列中的函数内,同样会有同步任务和异步任务,依次重复着5步,就是所说的Event Loop 事件循环
在异步任务将回调函数放入任务队列时,还会有两种情况,宏任务与微任务之分,宏任务会进入宏任务的任务队列,微任务放到微任务队列,执行任务队列时,会先执行微任务队列中的任务。
宏任务代表:ajax、setTimeout、setInterval
微任务代表:process.nextTick()、 new promise().then()的 .then()内的回调函数
- 只要微任务队列中有任务,就先执行微任务队里的任务,
- 执行完后,依次执行宏任务队里中的任务
- 在执行一轮宏任务的时候,在该宏任务内可能会注册一些新的微任务,放到的微任务对列
- 当该轮宏任务执行完,会检测到微任务队里中的新任务,在依次执行微任务对列中的任务
- 当微任务队里中的执行完后,会继续执行宏任务对列中的任务, 以此循环下去