【译】JavaScript中的async/await

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 异步的JavaScript从未如何简单!过去段时间,我们使用回调。然后,我们使用promises。现在,我们有了异步功能函数。

异步的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来处理异步函数中的任何错误。


注意: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') 
  })


image.png


假设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()


image.png


现在,假设你需要处理三个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()


image.png


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


有三个步骤:


  1. 创建三个promises


  1. 将三个promises添加到一个数组中


  1. 使用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()


image.png


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


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



相关文章
|
15天前
|
监控 JavaScript 前端开发
确定使用 `defer` 属性还是 `async` 属性来异步加载 JavaScript
【10月更文挑战第24天】选择使用 `defer` 属性还是 `async` 属性来异步加载 JavaScript 是一个需要综合考虑多个因素的决策。需要根据脚本之间的依赖关系、页面加载性能要求、脚本的功能和重要性等因素来进行权衡。在实际应用中,需要通过测试和验证来确定最适合的加载方式,以提供更好的用户体验和页面性能。
|
9天前
|
前端开发 JavaScript 开发者
除了 async/await 关键字,还有哪些方式可以在 JavaScript 中实现异步编程?
【10月更文挑战第30天】这些异步编程方式在不同的场景和需求下各有优劣,开发者可以根据具体的项目情况选择合适的方式来实现异步编程,以达到高效、可读和易于维护的代码效果。
|
10天前
|
JSON 前端开发 JavaScript
浅谈JavaScript中的Promise、Async和Await
【10月更文挑战第30天】Promise、Async和Await是JavaScript中强大的异步编程工具,它们各自具有独特的优势和适用场景,开发者可以根据具体的项目需求和代码风格选择合适的方式来处理异步操作,从而编写出更加高效、可读和易于维护的JavaScript代码。
18 1
|
30天前
|
JavaScript 前端开发 开发者
掌握Node.js中的异步编程:从回调到async/await
Node.js的异步编程模型是其核心特性之一,它使得开发者能够构建高性能和高并发的应用程序。本文将带你从Node.js的异步编程基础开始,逐步深入到回调函数、Promises、以及最新的async/await语法。我们将探讨这些异步模式的原理、使用场景和最佳实践,并通过实例代码展示如何在实际项目中应用这些概念。
|
2月前
|
前端开发 JavaScript 数据库连接
掌握 JavaScript 异步编程:从回调到 Async/Await
在现代 JavaScript 开发中,异步编程是处理非阻塞操作的关键技术。本文从早期的回调函数讲起,逐步过渡到 Promise 和 ES2017 的 async/await 语法,展示了异步编程如何变得更加简洁和强大。通过实用的技巧和最佳实践,帮助开发者避免常见陷阱,提升代码效率和可靠性。
|
1月前
|
前端开发 JavaScript 开发者
JavaScript 中的异步编程:深入了解 Promise 和 async/await
【10月更文挑战第8天】JavaScript 中的异步编程:深入了解 Promise 和 async/await
|
28天前
|
JSON 前端开发 JavaScript
探索JavaScript中的Async/Await:简化异步编程的利器
【10月更文挑战第12天】探索JavaScript中的Async/Await:简化异步编程的利器
16 0
|
29天前
|
前端开发 JavaScript UED
深入了解JavaScript异步编程:回调、Promise与async/await
【10月更文挑战第11天】深入了解JavaScript异步编程:回调、Promise与async/await
11 0
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
95 2
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的小区物流配送系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的小区物流配送系统附带文章源码部署视频讲解等
118 4