【译】JavaScript中的async/await

栏目: JavaScript · 发布时间: 5年前

内容简介:异步的异步函数能够使得(我们)编写异步JavaScript更加容易,但是,它自带一套陷阱,对初学者很不友好。在这个由两部分组成的文章中,我想分享下你需要了解的有关异步函数的内容。【PS:另一部分暂不打算翻译】

异步的 JavaScript 从未如何简单!过去段时间,我们使用回调。然后,我们使用 promises 。现在,我们有了异步功能函数。

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

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

异步功能

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

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

你也可以使用箭头函数。

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

异步函数总是返回promises

(异步函数)它不管你返回什么。其返回值都是 promise

const getOne = async _ => { 
  return 1 
} 

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

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

await关键字

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

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)。你可以直接退回承诺。

如果你 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') 
  })
复制代码
【译】JavaScript中的async/await

假设 getOne 需要一秒来解析。为了创建这个延迟,我们将 1000 (一秒)传入到 sleep 。一秒过后, sleep promise解析后,我们返回值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()
复制代码
【译】JavaScript中的async/await

现在,假设你需要处理三个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()
复制代码
【译】JavaScript中的async/await

如果 getOnegetTwogetThree 可以同时获取,你将节省两秒钟。你可以使用 Promise.all 同时获取这三个promises。

有三个步骤:

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

如下所示:

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()
复制代码
【译】JavaScript中的async/await

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

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


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

看见未来

看见未来

余晨 / 浙江大学出版社 / 2015-4-15 / 59.00元

【内容简介】 这是互联网群星闪耀的时代,巨人们用最尖端的技术和自成体系的哲学改变着我们的生活,甚至影响了整个世界和人类的历史进程。在这个时代,没有人可以避开互联网的渗透。互联网早已不是简单的技术变革,人们正试图赋予其精神和内涵,以期互联网能更好地为人类所用。 本书中作者 面对面地采访了包括马克·扎克伯格、埃隆·马斯克、杨致远、凯文·凯利、克里斯·安德森、罗伯特·希勒、迈克尔·莫瑞茨、凯......一起来看看 《看见未来》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具