首页 > web前端 > js教程 > 初学者的JavaScript异步指南,等待示例

初学者的JavaScript异步指南,等待示例

Joseph Gordon-Levitt
发布: 2025-02-09 09:47:09
原创
394 人浏览过

A Beginner's Guide to JavaScript async/await, with Examples

掌握JavaScript异步操作:Async/Await详解

本文深入探讨JavaScript中的async/await,教你如何高效掌控异步操作,编写更清晰易读的代码。

核心要点:

  • JavaScript中的async/await简化了异步操作的处理,使代码看起来像同步执行,但实际上仍然是非阻塞的。
  • async函数返回一个Promise,await关键字暂停函数执行,直到Promise解决,从而增强代码的可读性和流程控制。
  • async函数的错误处理可以使用try/catch块或Promisecatch()方法高效管理。
  • 使用Promise.all可以优化并行运行异步命令,允许多个Promise同时解决,而不是顺序执行。
  • 异步迭代器和for...of循环允许在循环中正确处理async函数,确保正确的执行顺序和更好的性能管理。
  • ES2022引入的顶层await允许在ES模块的顶层使用await,简化了异步代码的集成,无需额外的包装器。

内容概要:

  1. 如何创建JavaScript异步函数
    • async关键字
    • await关键字
    • 声明异步函数的不同方法
  2. JavaScript await/async底层使用Promise
    • 从Promise切换到async/await
  3. 异步函数中的错误处理
    • 使用函数调用的catch()方法
  4. 并行运行异步命令
  5. 同步循环中的异步await
  6. 顶层await
  7. 自信地编写异步代码

在JavaScript中,一些操作是异步的。这意味着它们产生的结果或值不会立即可用。

考虑以下代码:

function fetchDataFromApi() {
  // 数据获取逻辑
  console.log(data);
}

fetchDataFromApi();
console.log('数据获取完成');
登录后复制
登录后复制

JavaScript解释器不会等待异步fetchDataFromApi函数完成,然后才执行下一条语句。因此,它会在记录API返回的实际数据之前记录数据获取完成

在许多情况下,这不是预期的行为。幸运的是,我们可以使用asyncawait关键字来使我们的程序等待异步操作完成,然后再继续执行。

此功能在ES2017中引入JavaScript,并受所有现代浏览器支持。

如何创建JavaScript异步函数

让我们仔细看看fetchDataFromApi函数中的数据获取逻辑。JavaScript中的数据获取是异步操作的一个主要示例。

使用Fetch API,我们可以这样做:

function fetchDataFromApi() {
  // 数据获取逻辑
  console.log(data);
}

fetchDataFromApi();
console.log('数据获取完成');
登录后复制
登录后复制

这里,我们从JokeAPI获取一个编程笑话。API的响应采用JSON格式,因此在请求完成后(使用json()方法)我们提取该响应,然后将笑话记录到控制台。

请注意,JokeAPI是一个第三方API,因此我们无法保证返回的笑话质量!

如果我们在浏览器或Node(使用--experimental-fetch标志的17.5 版本)中运行此代码,我们会看到控制台仍然以错误的顺序记录内容。

让我们改变一下。

async关键字

我们需要做的第一件事是将包含函数标记为异步函数。我们可以使用async关键字来实现这一点,我们将它放在function关键字的前面:

function fetchDataFromApi() {
  fetch('https://v2.jokeapi.dev/joke/Programming?type=single')
    .then(res => res.json())
    .then(json => console.log(json.joke));
}

fetchDataFromApi();
console.log('数据获取完成');
登录后复制

异步函数始终返回一个Promise(稍后详细介绍),因此只需将then()链接到函数调用即可获得正确的执行顺序:

async function fetchDataFromApi() {
  fetch('https://v2.jokeapi.dev/joke/Programming?type=single')
    .then(res => res.json())
    .then(json => console.log(json.joke));
}
登录后复制

如果我们现在运行代码,我们会看到类似这样的内容:

fetchDataFromApi()
  .then(() => {
    console.log('数据获取完成');
  });
登录后复制

但我们不想这样做!JavaScript的Promise语法可能会有点复杂,这就是async/await闪光的地方:它使我们能够使用看起来更像同步代码的语法来编写异步代码,并且更易于阅读。

await关键字

接下来要做的是在函数中任何异步操作的前面加上await关键字。这将强制JavaScript解释器“暂停”执行并等待结果。我们可以将这些操作的结果分配给变量:

<code>程序员的浪漫:一行代码解决千行代码的bug。
数据获取完成</code>
登录后复制

我们还需要等待调用fetchDataFromApi函数的结果:

async function fetchDataFromApi() {
  const res = await fetch('https://v2.jokeapi.dev/joke/Programming?type=single');
  const json = await res.json();
  console.log(json.joke);
}
登录后复制

不幸的是,如果我们现在尝试运行代码,我们会遇到一个错误:

await fetchDataFromApi();
console.log('数据获取完成');
登录后复制

这是因为我们不能在非模块脚本的async函数之外使用await。我们稍后将更详细地介绍这一点,但现在解决这个问题最简单的方法是用它自己的函数包装调用代码,我们也将其标记为async

<code>Uncaught SyntaxError: await is only valid in async functions, async generators and modules</code>
登录后复制

如果我们现在运行代码,所有内容都应该按正确的顺序输出:

async function fetchDataFromApi() {
  const res = await fetch('https://v2.jokeapi.dev/joke/Programming?type=single');
  const json = await res.json();
  console.log(json.joke);
}

async function init() {
  await fetchDataFromApi();
  console.log('数据获取完成');
}

init();
登录后复制

我们需要这个额外的样板代码这一事实是不幸的,但在我看来,代码仍然比基于Promise的版本更容易阅读。

声明异步函数的不同方法

前面的示例使用了两个命名函数声明(function关键字后跟函数名),但我们并不局限于此。我们还可以将函数表达式、箭头函数和匿名函数标记为async

如果您想回顾一下函数声明和函数表达式之间的区别,请查看我们的指南

(后续内容同理,根据原文逐段改写,保持原意,并调整语言风格,使之更流畅自然)

以上是初学者的JavaScript异步指南,等待示例的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板