async/await 小技巧

sleep 函数

以前只接使用 setTimeout 和回调函数实现一个 sleep 会有很多的副作用,用起来很不方便。

所以让 setTimeout 搭配使用 async/await

const sleep = delay => {
  return new Promise(resolve => {
    setTimeout(resolve, delay)
  })
}

const fn = async _ => {
  console.log('starting....')
  await sleep(1000)
  console.log('after sleeping for 1 second')
}

搭配 map() 函数

在 map 中引入异步处理:

const arr = [1,2,3,4,5]
const asyncFn = data => {
  // 异步处理函数
}

const results = arr.map(async num => {
  await asyncFn(num)
  return ++num
})

console.log(results)

代码执行后的结果 [Promise, Promise, Promise, Promise, Promise] 而且 map 函数并不会等异步函数 asyncFn 执行完毕后再返回结果

既然 async 执行后会返回一个 Promise 对象,所以可以通过 Promise.all 的状态来判断异步函数的状态:

const arr = [1,2,3,4,5]
const asyncFn = data => {
  // 异步处理函数
}
const p = arr.map(async num => {
  await asyncFn(num)
  return ++num
})

Promise.all(p).then(results => {
  console.log(results)
})

这样就能正常返回结果 [2, 3, 4, 5, 6]

使用 await 代替 then() 函数

上面的例子最后使用了 Promise.all 还是回到了使用回调函数的方式

这个也很好解决,只需要在外层再加一个 async 函数

const main = async _ => {
  const results = await Promise.all(arr.map(num => {
    await asyncFn()
    return ++num
  }))
  console.log(results)
}

main()

搭配 reduce() 函数

通过引入 async/await 可以把 reduce 扩展成一个按顺序执行异步函数的工具

reduce 用起来很简单:

const arr = [1,2,3,4,5]
const result = arr.reduce((prev, next) => {
  return prev+next
}, 0)

console.log(result)

像 map 函数一样引入 async/await :

const arr = [1,2,3,4,5]
const main = async _ => {
  const result = await arr.reduce(async (prev, next) => {
    const tmp = await prev
    return tmp + next
  }, Promise.resolve(0))

  console.log(result)
}

main()

而且还可以在 reduce 内部加入异步函数:

const arr = [1,2,3,4,5]
const main = async _ => {
  const result = await arr.reduce(async (prev, next) => {
    const tmp = await prev

    // 异步处理 暂停1s
    await sleep(1000)
    console.log(tmp + next)

    return tmp + next
  }, Promise.resolve(0))
}

main()

上述代码会每隔一秒依次打出 1 3 6 10 15

参考自

http://fred-zone.blogspot.hk/2017/04/javascript-asyncawait.html
http://2ality.com/2016/10/async-function-tips.html

FLYLEE