当前位置:首页 > 技术分析 > 正文内容

JavaScript异步编程新纪元:Async/Await详解

ruisui883个月前 (02-14)技术分析11

在JavaScript中,异步编程是处理耗时操作(如网络请求、定时器等)的关键。传统的回调函数方式常常导致代码难以理解和维护,而 Promise 的出现,让异步代码更加结构化。 然而,Promise 链式调用在处理复杂逻辑时仍然略显繁琐。为了进一步简化异步代码的编写,JavaScript 引入了 async/await 语法。本文将深入探讨 async/await 的工作原理和使用方法,带你进入更优雅的异步编程世界。

async函数:异步的起点

async 关键字用于声明一个异步函数。 当我们将 async关键字添加到函数声明前时,该函数就会变成一个异步函数。异步函数有以下两个关键特性:

  1. 隐式返回Promise:
    无论异步函数返回什么值,它都会被包装成一个
    Promise 对象。 如果函数返回一个普通值,那么 Promise 的状态将是 resolved,其值将是返回的普通值。如果函数内部抛出错误,那么 Promise 的状态将是 rejected,错误信息将被传递。
  2. 包含异步操作的函数:
    async 函数通常用于处理异步操作,例如使用 setTimeoutfetch 等。虽然它内部可以包含同步代码,但主要目的是为了更容易地处理异步流程。

下面是一个简单的 async 函数示例:

async function f() {
  return 1;
}

f().then(alert); // 输出 1

在这个例子中,f 函数被声明为异步函数,它返回数字 1。 然而,调用 f() 时,我们并没有直接拿到数字 1,而是得到了一个 resolved 状态的 Promise。我们可以通过 then() 方法访问 Promise 的值,并使用 alert 展示。

await关键字:等待异步结果

await 关键字只能在 async 函数内部使用,它的作用是暂停 async 函数的执行,直到一个 Promise 对象变成 resolvedrejected 状态。await 关键字会返回 Promise 对象的状态值。

  1. 等待Promise resolved:
    await 等待的 Promise 变为 resolved 状态时,await 会返回该 Promise 的值,然后 async函数会继续向下执行。
  2. 等待Promise rejected:
    await 等待的 Promise 变为 rejected 状态时,await 会抛出该 Promise 传递的错误信息,我们可以使用 try...catch 块来捕获这个错误。

下面是一个 await 的使用示例:

async function f() {
  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("done!"), 1000);
  });

  let result = await promise; // wait until the promise resolves
  alert(result); // "done!"
}

f();

在这个例子中,f 函数使用 setTimeout 创建了一个 Promiseawait promise 会暂停 f 函数的执行,直到 Promiseresolve,返回值为 "done!",然后 alert 显示这个结果。

async/await的优势

  1. 简化异步代码:
    相比于 Promise 的链式调用,async/await 可以使异步代码更像是同步代码,更容易理解和维护。
  2. 更清晰的错误处理:
    async/await 结合 try...catch 块可以更方便地处理异步操作的错误,避免了 Promise 链式调用中容易出现的错误处理遗漏。
  3. 代码可读性提升:
    通过使用
    async/await,我们可以避免使用大量的 then 方法,使代码更加简洁和易读。

实践案例

我们来看一个实际的例子: 使用 async/await 发起一个网络请求。

async function fetchData() {
  try {
    const response = await fetch("https://api.example.com/data");
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const data = await response.json();
    console.log(data);
    return data;
  } catch (error) {
    console.error("Failed to fetch data:", error);
  }
}

fetchData();

这个例子使用 fetch 发起一个 HTTP 请求,并通过 await 等待响应。通过 try...catch 块,我们可以捕获请求过程中的错误。这样的代码相比传统的 Promise 写法,更简洁也更容易理解。

async/await的局限性

尽管 async/await 很强大,但也有一些局限性:

  1. 必须在 async 函数内使用:
    await 关键字只能在 async 函数内部使用,不能在顶层代码或普通函数中使用。
  2. Promise 为基础:
    async/await 本质上是 Promise 的语法糖,所以仍然基于 Promise。
  3. 不支持并发:
    async 函数中,await 会逐个等待 Promise 完成,无法并行执行多个异步操作。如果需要并发执行异步操作,可以使用 Promise.all 等方法。

总结

async/await 是 JavaScript 中非常重要的异步编程特性,它大大简化了异步代码的编写和维护。 通过 async关键字声明异步函数,我们可以使函数默认返回 Promise,通过 await 关键字,可以暂停函数执行,直到 Promise 完成。 希望本文能够帮助你更好地理解和使用 async/await

在实际开发中,你是否经常使用 async/await 呢?欢迎在评论区分享你的经验和看法。

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/1948.html

标签: aysnc
分享给朋友:

“JavaScript异步编程新纪元:Async/Await详解” 的相关文章

使用cgroup限制进程资源

这里使用containerd项目中的cgroup包来实现进程资源限制。先写一个耗费一个CPU并且一秒增加10m内存的测试进程package mainimport ( "fmt" "math/rand" "time")func main() { go f...

「云原生」Containerd ctr,crictl 和 nerdctl 命令介绍与实战操作

一、概述作为接替Docker运行时的Containerd在早在Kubernetes1.7时就能直接与Kubelet集成使用,只是大部分时候我们因熟悉Docker,在部署集群时采用了默认的dockershim。在V1.24起的版本的kubelet就彻底移除了dockershim,改为默认使用Conta...

HTML5+眼球追踪?黑科技颠覆传统手机体验

今天,iH5工具推出一个新的神秘功能——眼动追踪,可以通过摄像头捕捉观众眼球活动!为了给大家具体演示该功能的使用,我做了一个案例,供大家参考。实际效果如下:案例比较简单,就是通过眼动功能获取视觉焦点位置,剔除用户看中的牌。现在,舞台的属性中多了一个“启用眼动”的选项,另外,还多了一个“启用摄像头”的...

佳能 EOS R8 深度评测

佳能 EOS R8 的定位是入门级全画幅无反光镜可换镜头相机。尽管在产品阵容中处于这一位置,R8 仍然是一个强大的相机,配备了先进的 R6 II 同款成像传感器、快速处理器和令人难以置信的自动对焦系统,体积小、重量轻、价格低。这款相机是发烧友、旅行者、家庭以及任何想要全画幅传感器相机的人的绝佳选择。...

微信小程序发展越来越快,Flutter应用开发越来越低效?

目前的疑惑微信小程序发展的越来越快,目前小程序甚至取代了大部分 App 的生态位,公司的坑位不增反降,只能让原生应用开发兼顾或换岗进行小程序的开发。以我的实际情况来讲,公司应用采用的 Flutter 框架,同样的功能不可避免的就会存在 Flutter 应用开发和微信小程序开发兼顾的情况,这种重复造轮...

微信正开发“应用号”取代手机应用

长江商报消息用户只需关注公众号,不必下载APP就可获得相同体验本报讯(记者 陈妮希)昨日,2016微信公开课PRO版在广州举行,腾讯公司高级执行副总裁、微信事业群总裁张小龙首次公开演讲,并透露微信正在开发“应用号”,将应用和订阅号相结合。现场,微信团队还首次发布了腾讯生物识别标准“TENCENTSO...