(本来想吐槽下去年才熟练使用Promise但是又要用async-await,但是async-await炒鸡好用,默默流泪)
Async/Await与Promise的关系
async-await是promise和generator的语法糖,意在优化promise的写法,简单的说async-await是用来简化pormise写法的,并不是取代关系。
Async/Await基本语法
  Async放在function关键字前面,await放在Async关键字的函数里,并且最终返回一个promise对象。如下代码所示:
  1
2
3
4
5
6
7
8
9
10
11
12async function asyncAwaitDemo(){
    const result = await new Promise((resolve, reject)=>{
        setTimeout(()=>{
            resolve('test')
        },200)
    })
    return result;
}
asyncAwaitDemo().then((r)=>{
    console.log('result:',r);
})
// result: test
  需要注意的是await只能放在async关键声明的函数里(这点和yield与*的关系一致)
  1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17// 正常 for 循环
async function demo() {
    let arr = [1, 2, 3, 4, 5];
    for (let i = 0, len = arr.length; i < len; i ++) {
        await arr[i];
    }
}
demo();//正常输出
//如果for循环写成下面这样
async function bugDemo() {
    let arr = [1, 2, 3, 4, 5];
    arr.forEach(item => {
        await item;
    });
}
bugDemo();// Uncaught SyntaxError: Unexpected identifier
场景示例
  这里写一个简单模拟异步api
  1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27  class Api {
  constructor () {
    this.user = { id: 1, name: 'test' }
    this.friends = [ this.user, this.user, this.user ]
    this.photo = 'not a real photo'
  }
  getUser () {
    return new Promise((resolve, reject) => {
      setTimeout(() => resolve(this.user), 200)
    })
  }
  getFriends (userId) {
    return new Promise((resolve, reject) => {
      setTimeout(() => resolve(this.friends.slice()), 200)
    })
  }
  getPhoto (userId) {
    return new Promise((resolve, reject) => {
      setTimeout(() => resolve(this.photo), 200)
    })
  }
  throwError () {
    return new Promise((resolve, reject) => {
      setTimeout(() => reject(new Error('Intentional Error')), 200)
    })
  }
}
需求1:获得用户信息
  promise链写法
  1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16  function promiseChain () {
  const api = new Api()
  let user, friends
  api.getUser()
    .then((returnedUser) => {
      user = returnedUser
      return api.getFriends(user.id)
    })
    .then((returnedFriends) => {
      friends = returnedFriends
      return api.getPhoto(user.id)
    })
    .then((photo) => {
      console.log('promiseChain', { user, friends, photo })
    })
}
Async/Await写法
1  | async function asyncAwaitIsYourNewBestFriend () {  | 
需求2:获得朋友的朋友
 promise链写法:这里使用的是迭代循环
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 function promiseLoops () {  
  const api = new Api()
  api.getUser()
    .then((user) => {
      return api.getFriends(user.id)
    })
    .then((returnedFriends) => {
      const getFriendsOfFriends = (friends) => {
        if (friends.length > 0) {
          let friend = friends.pop()
          return api.getFriends(friend.id)
            .then((moreFriends) => {
              console.log('promiseLoops', moreFriends)
              return getFriendsOfFriends(friends)
            })
        }
      }
      return getFriendsOfFriends(returnedFriends)
    })
}
 Async/Await写法:
 1
2
3
4
5
6
7
8
9 async function asyncAwaitLoops () {
  const api = new Api()
  const user = await api.getUser()
  const friends = await api.getFriends(user.id)
  for (let friend of friends) {
    let moreFriends = await api.getFriends(friend.id)
    console.log('asyncAwaitLoops', moreFriends)
  }
}
  Async/Await写法简化并发
  1
2
3
4
5
6
7
8  async function asyncAwaitLoopsParallel () {
  const api = new Api()
  const user = await api.getUser()
  const friends = await api.getFriends(user.id)
  const friendPromises = friends.map(friend => api.getFriends(friend.id))
  const moreFriends = await Promise.all(friendPromises)
  console.log('asyncAwaitLoopsParallel', moreFriends)
}
  参考: