【译】JavaScript中的async/await

异步的JavaScript从未如何简单!过去段时间,咱们使用回调。而后,咱们使用promises。如今,咱们有了异步功能函数。javascript

异步函数可以使得(咱们)编写异步JavaScript更加容易,可是,它自带一套陷阱,对初学者很不友好。java

在这个由两部分组成的文章中,我想分享下你须要了解的有关异步函数的内容。【PS:另外一部分暂不打算翻译】git

异步功能

异步功能函数包含async关键词。你能够在正常的函数声明中使用它:github

async function functionName (arguments) {
  // Do something asynchronous
}
复制代码

你也能够使用箭头函数。数组

const functionName = async (arguments) => {
  // Do something asynchronous
}
复制代码

异步函数老是返回promises

(异步函数)它无论你返回什么。其返回值都是promisepromise

const getOne = async _ => { 
  return 1 
} 

const promise = getOne()
console.log(promise) // Promise 
复制代码

笔记:在接着往前读以前,你应该知道什么是JavaScript Promises知识点,以及如何使用它们。不然,它会开始变得混乱。这篇文章会帮助你熟悉JavaScript Promise。异步

await关键字

当你调用promise时,你会在then中处理下一步,以下:async

const getOne = async _ => { 
  return 1 
} 

getOne()
  .then(value => {
    console.log(value) // 1
  })
复制代码

await关键字容许你等待promise去解析。一旦解析完promise,它就会返回参数传递给then调用。函数

const test = async _ => {
  const one = await getOne()
  console.log(one) // 1
}

test()
复制代码

返回await

在返回承诺(promise)以前没有必要等待(await)。你能够直接退回承诺。post

若是你return await些内容,则你首先是解决了原先promise。而后,你从已经解析的内容(resolved value)建立新的promise。return await真的没作什么有效的东西。无需额外的步骤。

// Don't need to do this 
const test = async _ => {
  return await getOne()
}

test()
  .then(value => {
    console.log(value) // 1
  })
复制代码
// Do this instead
const test = async _ => {
  return getOne()
}

test()
  .then(value => {
    console.log(value) // 1
  })
复制代码

注意:若是你不须要await,则不须要使用异步功能(async function)。上面的例子能够改写以下:

// Do this instead
const test = _ => {
  return getOne()
}

test()
  .then(value => {
    console.log(value) // 1
  })
复制代码

处理错误

若是一个promise出错了,你能够使用catch调用来处理它,以下所示:

const getOne = async (success = true) => { 
  if (success) return 1
  throw new Error('Failure!')
} 

getOne(false)
  .catch(error => console.log(error)) // Failure!
复制代码

若是你想在一个异步函数中处理错误,你须要调用try/catch

const test = async _ => {
  try {
    const one = await getOne(false)
  } catch (error) {
    console.log(error) // Failure!
  }
}

test()
复制代码

若是你有多个await关键字,错误处理可能变得很难看...

const test = async _ => {
  try {
    const one = await getOne(false)
  } catch (error) {
    console.log(error) // Failure!
  }

  try {
    const two = await getTwo(false)
  } catch (error) {
    console.log(error) // Failure!
  }

  try {
    const three = await getThree(false)
  } catch (error) {
    console.log(error) // Failure!
  }
}

test()
复制代码

还有更好的方法。

咱们知道异步函数老是返回一个promise。当咱们调用promise时,咱们能够在catch调用中处理错误。这意味着咱们能够经过添加.catch来处理异步函数中的任何错误。

const test = async _ => {
  const one = await getOne(false)
  const two = await getTwo(false)
  const three = await getThree(false)
}

test()
  .catch(error => console.log(error)))
复制代码

注意:Promise的catch方法只容许你捕获一个错误。

多个awaits

await阻止JavaScript执行下一行代码,直到promise解析为止。这可能会致使代码执行速度减慢的意外效果。

为了实际演示这点,咱们须要在解析promise以前建立一个延迟。咱们能够使用sleep功能来建立延迟。

const sleep = ms => {
  return new Promise(resolve => setTimeout(resolve, ms))
}
复制代码

ms是解析前等待的毫秒数。若是你传入1000sleep函数,JavaScript将等待一秒才能解析promise。

// Using Sleep
console.log('Now')
sleep(1000)
  .then(v => { 
    console.log('After one second') 
  })
复制代码

sleep

假设getOne须要一秒来解析。为了建立这个延迟,咱们将1000(一秒)传入到sleep。一秒事后,sleeppromise解析后,咱们返回值1。

const getOne = _ => {
  return sleep(1000).then(v => 1)
}
复制代码

若是你使用await getOne(),你会发如今getOne解析以前须要一秒钟。

const test = async _ => {
  console.log('Now')

  const one = await getOne()
  console.log(one)
}

test()
复制代码

block-1

如今,假设你须要处理三个promises。每一个promise都有一秒钟的延迟。

const getOne = _ => {
  return sleep(1000).then(v => 1)
}

const getTwo = _ => {
  return sleep(1000).then(v => 2)
}

const getThree = _ => {
  return sleep(1000).then(v => 3)
}
复制代码

若是你连续await这三个promises,你将要等待三秒才能解析完全部promises。这并很差,由于咱们强迫JavaScript在作咱们须要作的事情以前等待了两秒钟。

const test = async _ => {
  const one = await getOne()
  console.log(one)

  const two = await getTwo()
  console.log(two)

  const three = await getThree()
  console.log(three)

  console.log('Done')
}

test()
复制代码

block-2

若是getOnegetTwogetThree能够同时获取,你将节省两秒钟。你能够使用Promise.all同时获取这三个promises。

有三个步骤:

  1. 建立三个promises
  2. 将三个promises添加到一个数组中
  3. 使用Promise.allawaitpromises数组

以下所示:

const test = async _ => {
  const promises = [getOne(), getTwo(), getThree()]
  console.log('Now')

  const [one, two, three] = await Promise.all(promises)
  console.log(one)
  console.log(two)
  console.log(three)

  console.log('Done')
}

test()
复制代码

block-3

这就是你须要了解的基本异步功能函数!我但愿这篇文章为你扫除了些障碍。

笔记:这篇文章是Learn JavaScript的修改摘录。若是你发现本文有用,你可能须要去查看它。

后话

原文:zellwk.com/blog/async-…

文章首发:github.com/reng99/blog…

至此,系列文callbacks,promisesasync/await共三篇文章已经完成~

更多内容:github.com/reng99/blog…

相关文章
相关标签/搜索