Hot For Coding
ES7大招async await

JavaScript异步编写多了以后会特别不好维护,虽然也有一些第三方库专门解决这个问题,但并没有根本性解决这个问题,ES每一版都在想着怎么解决异步编写,Promise显然未能解决这个问题,于是在ES7推出了async await两个关键字,先来看一下简单的使用

let wait = () => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('wait...')
    }, 1000)
  })
}
 
(async () => {
  console.log('start...')
  console.log(await wait())
  console.log('end...')
})()
 
// Outputs:
//  start...
//  wait...
//  end...

看起来是不是很好用,配合fetch可以这样用

fetch.json

{
  "title": "本篇文章介绍Async与await的使用",
  "author": "Nicholas Lee"
}

例子代码

(async () => {
  console.log('Start...')
  let respond = await fetch('./data.json')
  let json = await respond.json()
  console.log(json)
  console.log('end...')
})()
 
// Outputs:
// test.html:29 Start...
// test.html:32 {title: "本篇文章介绍Async与await的使用", author: "Nicholas Lee"}
// test.html:33 end...

注意: 在respond.json()前面一定要加await关键字,要不然结果就是这样

(async () => {
  console.log('Start...')
  let respond = await fetch('./data.json')
  let json = respond.json()
  console.log(json)
  console.log('end...')
})()
 
// Outputs:
//  test.html:29 Start...
//  test.html:32 Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: {…}}
//  test.html:33 end...

远程服务器的资源永远都是不确定的,所以为了保险我们还需要try catch捕获抛出的错误:

(async () => {
  console.log('Start...')
  try {
    let respond = await fetch('./data1.json')
    let json = await respond.json()
    console.log(json)
    console.log('')
  } catch (e) {
    console.error(e)
    console.log('Get some errors...')
  }
 
  console.log('End...')
})()
 
// Outputs:
// Start...
// test.html:57 GET http://localhost:3000/data1.json 404 (Not Found)
// (anonymous) @ test.html:57
// (anonymous) @ test.html:67
// test.html:62 SyntaxError: Unexpected token C in JSON at position 0
//     at test.html:58
//     at <anonymous>
// (anonymous) @ test.html:62
// async function (async)
// (anonymous) @ test.html:54
// (anonymous) @ test.html:67
// test.html:63 Get some errors...
// test.html:66 End...

如果你有一个异步队列,可以这样解决:

let wait = (n) => {
  return new Promise(resolve => {
    setTimeout(() => {
      n++
      resolve(n)
    }, 1000)
  })
}
 
(async () => {
  console.log('Start...')
  for (let i = 0; i < 5; i++) {
    console.log(await wait(i))
  }
  console.log('End...')
})()
 
// Outputs:
// test.html:20 Start...
// test.html:22 1
// test.html:22 2
// test.html:22 3
// test.html:22 4
// test.html:22 5
// test.html:24 End...

如果用map枚举处理也可以

let wait = (n) => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(`return_${n}`)
    }, 1000)
  })
}
 
(async () => {
  let arr = ['a', 'b', 'c', 'd']
  console.log('Start...')
  await Promise.all(arr.map(async (i) => {
    console.log(await wait(i))
  }))
 
  console.log('End...')
})()
 
// Outputs:
// test.html:20 Start...
// test.html:22 return_a
// test.html:22 return_b
// test.html:22 return_c
// test.html:22 return_d
// test.html:25 End...

以上记得用map而不是forEach。怎么样?async和await是不是还可以?

TITLE: ES7大招async await

LINK: https://www.qttc.net/486_await_async.html

NOTE: 转载内容请注明出处