异步

一、单线程与异步

  1. JS是单线程语言,只能同时做一件事
  2. 浏览器和nodeJS已经支持JS启动进程,如web worker
  3. JS和DOM渲染共用一个线程,因为JS可以修改DOM结构

什么时候需要使用异步?

  • 网络请求
  • 定时任务

异步使用的是callback形式

二、setTimeout、Promise、Async/Await 的区别

主要是来考察三者在事件循环中的区别。事件循环中分为宏观任务队列微观任务队列

JS是单线程的,对于异步操作只能先将其放在一边,按照某种规则按先后顺序放在某个容器中(其实就是宏观任务队列和微观任务队列)。先处理同步任务,再处理异步任务。异步任务分为宏观任务队列和微观任务队列。

宏观任务

  • script(整体代码)
  • setTimeout
  • setInterval
  • I/O
  • UI交互事件
  • postMessage
  • MessageChannel
  • setImmediate(Node.js 环境)

微观任务

  • Promise.then
  • MutaionObserver
  • process.nextTick(Node.js 环境)
  • async/await实际上是promise+generator的语法糖,也就是promise,也就是微观任务

执行顺序是同步任务结束后,先处理微观任务后处理宏观任务

setTimeout

1
2
3
4
5
6
7
console.log('script start')  //1. 打印 script start
setTimeout(() => {
console.log('setTimeout')// 4. 打印 setTimeout
}, 0) // 2. 调用 setTimeout 函数,并定义其完成后执行的回调函数
console.log('script end') //3. 打印 script start

// 输出顺序:script start->script end->setTimeout

注:就算设置的是0秒后执行,输出顺序也不会变

Promise

1
2
3
4
5
6
7
8
9
10
11
12
13
console.log('script start') // 1.同步任务
let promise1 = new Promise(function (resolve) {
console.log('promise1') // 2. 同步任务
resolve(console.log('resolve end')) // 3.同步任务
console.log('promise1 end') // 4. 同步任务
}).then(function () {
console.log('promise2') // 6. 微观任务
})
setTimeout(function(){
console.log('setTimeout') // 7. 宏观任务
})
console.log('script end') // 5. 同步任务
// 输出顺序: script start -> promise1 -> resolve end -> promise1 end -> script end -> promise2 -> setTimeout

Promise本身是同步的立即执行函数,而Promise.then()才是微观任务

Async/Await

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
async function async1(){
console.log('async1 start');
await async2();
console.log('async1 end')
}
async function async2(){
console.log('async2 start')
await async3();
console.log('async2 end')
}

let async3 = () => {
console.log('async3')
}

console.log('script start');
async1();
console.log('script end')

// 输出顺序 script start -> async1 start -> async2 start -> async3 -> script end -> async2 end -> async1 end

async返回一个Promise函数 ,遇到await会立即执行await后面的代码。而await下面的代码会放在微观任务队列中。

await的含义为等待,也就是 async 函数需要等待await后的函数执行完成并且有了返回结果(Promise对象)之后,才能继续执行下面的代码。await通过返回一个Promise对象来实现同步的效果。

Author: YangLeLe
Link: http://younglele.cn/asynchronous/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.