Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >await 只在 async 函数中工作

await 只在 async 函数中工作

作者头像
前端开发博客
发布于 2020-11-04 03:34:00
发布于 2020-11-04 03:34:00
1.6K00
代码可运行
举报
文章被收录于专栏:前端开发博客前端开发博客
运行总次数:0
代码可运行

关于 promise 的一种更优雅的写法 async/await 中,await 只会出现在 async 函数中,我们使用 async/await 时,几乎不需要 .then,因为 await 为我们处理等待;但是在代码的顶层,当我们在 async 函数的外部时,我们在语法上是不能使用 await 的,所以通常添加 .then/catch 去处理最终结果或者 error。

有一种特殊的语法可用一种更舒适的方式使用 promise,称为 “async/await”。它的易于理解和使用简单让人惊讶。

Async 函数

我们从 async 关键字开始。它可以放在函数前,就像这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
async function f() {
  return 1;
}

函数前的 “async” 意味着一件简单的事情:函数总是会返回 promise。如果代码中有 return<non-promise>,那么 JavaScript 就会自动将其封装到一个带有该值的 resolved promise 中。

例如,上述代码中返回一个带有结果 1 的 resolved promise,我们可以进行测试:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
f().then(alert); // 1

…我们可以显式的返回一个 promise,结果相同:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
async function f() {
    return Promise.resolve(1);
}

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

因此, async 确保函数返回一个 promise,并在其中封装非 promise。很简单对吧?但不仅仅如此。因为还有 await 关键字,它只在 async 函数中工作,而且非常酷。

Await

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 只在 async 函数中工作 
    let value = await promise;

await 关键字使 JavaScript 等待,直到 promise 得到解决并返回其结果。

下面是一个 promise 在 1s 之后 resolve 的例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
async function f() {

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

  let result = await promise; // 等待,直到 promise 执行 resolves (*)

  alert(result); // “done!”
}

f();

函数在 (*) 行执行“暂停”,并在 promise 被处理时继续执行, result 变成其结果。上述代码在一秒内显示了 “done!”

我们强调: await 字面上是让 JavaScript 等待 promise 完成,然后继续处理结果。这并不会消耗 CPU 资源,因为引擎可以同时处理其他任务:执行其他脚本,处理事件等。

这是一种比 promise.then 更优雅地获取 promise 结果的语法,它更容易阅读和编写。

不能在常规函数中使用 await 如果我们尝试在非 async 函数中使用 await,就会产生语法错误: function f() { let promise = Promise.resolve(1); let result = await promise; // 语法错误 }

我们用 Promises 链 章节 showAvatar() 示例开始,并使用 async/await 重写它:

  1. 我们需要用 await 替换 .then 调用。
  2. 此外,我们应该使用 async 函数来工作。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
async function showAvatar() {

  // 读取我们的 JSON
  let response = await fetch('/article/promise-chaining/user.json');
  let user = await response.json();

  // 读取 GitHub 用户信息
  let githubResponse = await fetch(\`https://api.github.com/users/${user.name}\`);
  let githubUser = await githubResponse.json();

  // 显示化身
  let img = document.createElement('img');
  img.src = githubUser.avatar_url;
  img.className = "promise-avatar-example";
  document.body.append(img);

  // 等待 3 秒
  await new Promise((resolve, reject) => setTimeout(resolve, 3000));

  img.remove();

  return githubUser;
}

showAvatar();

非常整洁,而且易于阅读,对吧?比之前好多了。

await 在顶层代码中无效 刚开始使用 await 的新手往往会忘记这一点,但我们不能在最顶层的代码中编写 await,因为它会无效: // 在顶层代码中导致语法错误 let response = await fetch('/article/promise-chaining/user.json'); let user = await response.json(); 所以我们需要将 await 代码封装在一个async 函数中。就像上述例子一样。 async/awaitpromise.then/catch 我们使用 async/await 时,几乎不需要 .then,因为 await 为我们处理等待。我们也可以使用 try..catch 替代 .catch。但这通常(并不总是)更方便。 但是在代码的顶层,当我们在 async 函数的外部时,我们在语法上是不能使用 await 的,所以通常添加 .then/catch 去处理最终结果或者 error。 与上述示例的 (*) 行一样。

总结

函数前的 async 关键字有两个作用:

  1. 总是返回 promise。
  2. 允许在其中使用 await

在 promise 之前的 await 关键字,使 JavaScript 等待 promise 被处理,然后:

  1. 如果有 error,就会产生异常,就像在那个地方调用了 throwerror 一样。
  2. 否则,就会返回值,我们可以给它分配一个值。

它们一起为编写易于读写的异步代码提供了一个很好的框架。

对于 async/await,我们很少需要编写 promise.then/catch,但我们不应该忘记它们是基于 promise 的。因为有时(例如,在最外面的范围)我们不得不使用这些方法。 Promise.all 也是一个很好的东西,它能够同时等待很多任务。

参考:https://zh.javascript.info/async-await

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-11-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端开发博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
37 - Async/Await : 简介​
Callbacks 和 promise 很好地解决了异步操作。Promise 比 callback 改进的地方在提供了扁平的语法,特别是遇到链式 promise 的时候。promise 包含的操作符 allSettled、any、then、catch 使得应对复杂的异步操作更自如。
前端黑板报
2022/12/01
2290
原来异步函数用起来这么“香”?不信来试试
从loadJson抛出的错误由.catch处理。我们不能在这里使用await loadJson(…),因为我们不是在一个异步函数中。
公众号---人生代码
2021/03/16
4010
盘点JavaScript中async/await知识
Async/await 是以更舒适的方式使用 promise 的一种特殊语法,同时它也非常易于理解和使用。
前端进阶者
2021/07/22
4240
盘点JavaScript中的Promise 链的高级用法
它的理念是将 result 通过 .then 处理程序(handler)链进行传递。
前端进阶者
2021/08/13
1.2K0
20分钟带你掌握JavaScript Promise和 Async/Await
一般在开发中,查询网络API操作时往往是比较耗时的,这意味着可能需要一段时间的等待才能获得响应。因此,为了避免程序在请求时无响应的情况,异步编程就成为了开发人员的一项基本技能。
葡萄城控件
2020/12/14
7150
[译]带你理解 Async/await
「async/await」是 promises 的另一种更便捷更流行的写法,同时它也更易于理解和使用。
savokiss
2019/11/06
1.2K0
握异步编程新利器——深入理解async/await
对于程序员来说,异步编程是我们在日常软件开发中不可避免的一部分,它可以让我们的程序更加高效、响应更加迅速。在 JavaScript 中,异步编程通常使用回调函数来实现,但是这种方式往往会导致代码可读性差、难以维护。为了解决这个问题,ES2017 引入了 async/await 语法,使得异步编程变得更加简单和易读。本篇博客将介绍 async/await 的基本概念,并提供一些实战案例,帮助初学者更好地掌握这种编程方式。
Front_Yue
2024/01/15
1.1K0
握异步编程新利器——深入理解async/await
async/await 带你逃离回调地狱
Gcaufy
2017/05/18
2.2K0
async/await 带你逃离回调地狱
async/await语法
async/await 是 JavaScript 中用于处理异步操作的语法,它简化了 Promise 的使用,使得异步代码更加易读和易写。
GeekLiHua
2025/01/21
1080
async/await初学者指南
在JavaScript中,一些操作是异步的。这意味着它们产生的结果或者值不会立即奏效。
chuckQu
2023/09/01
3940
async/await初学者指南
ES6-语法基础
箭头函数是把函数简写成一个表达式;如果只有一个参数,()可以省略;如果只有一个行,{ }可以省略,return 可以省略。
用户10175992
2022/11/15
4880
ES6-语法基础
《现代Javascript高级教程》JavaScript中的Generator函数
在JavaScript的世界里,异步编程是一个核心的主题,而Generator函数和Async/Await则是它的重要部分。这篇文章将深入讨论Generator函数和它在实现Async/Await中的作用,帮助你更深入的理解这两个重要概念。
linwu
2023/07/27
2360
Promise与Async/Await:异步编程的艺术
一个Promise对象代表了一个现在、将来或永远可能可用,也可能不可用的值。它有三种状态:pending(进行中)、fulfilled(已成功)或rejected(已失败)。
空白诗
2024/06/14
2060
async/await
​ 如果await 后面直接跟的为一个变量,比如:await 1;这种情况的话相当于直接把await后面的代码注册为一个微任务,可以简单理解为promise.then(await下面的代码)。然后跳出async1函数,执行其他代码,当遇到promise函数的时候,会注册promise.then()函数到微任务队列,注意此时微任务队列里面已经存在await后面的微任务。
hss
2022/02/25
2380
JavaScript基础——深入学习async/await
大家好,上周我们一起学习了《JavaScript基础——Promise使用指南》, 明白了ES6增加的新特性——Promise让我们能够更加优雅的书写回调函数,清楚了Promise有哪些状态,以及如何编写Promise的相关代码。本篇文章,小编将和大家一起学习异步编程的未来——async/await,它会打破你对上篇文章Promise的认知,竟然异步代码还能这么写! 但是别太得意,你需要深入理解Promise后,才能更好的的驾驭async/await,因为async/await是基于Promise的,没有理解Promise,小编强烈建议各位再看看《JavaScript基础——Promise使用指南》。
前端达人
2018/12/17
1.9K2
JavaScript基础——深入学习async/await
async/await详解
async/await是ES20717引入的,主要是简化Promise调用操作,实现了以异步操作像同步的方式去执行,async外部是异步执行的,同步是await的作用。
不叫猫先生
2023/11/25
2.6K0
JavaScript进阶-async/await语法糖
自从ES2017引入了async/await,JavaScript异步编程迎来了新的春天。async/await以其简洁的语法和直观的流程控制,极大地降低了异步编程的复杂度。本文将深入浅出地探讨async/await的工作原理、常见应用场景、易错点及其规避策略,并通过具体代码示例来加深理解。
Jimaks
2024/06/21
1940
JavaScript进阶-async/await语法糖
ES2017 异步函数的最佳实践(`async` /`await`)
简单来说,async函数是 promise 的 "语法糖"。它们允许我们使用更熟悉的语法来模拟同步执行,从而代替 promise 链式写法。
秋风的笔记
2020/10/27
1.8K0
async/await 和 promise
所以我写这个的文章,主要还是交流学习,如果您已经清楚了eventloop/async/await/promise 这些东西呢,可以 break 啦。
grain先森
2019/03/28
7080
async/await 和 promise
掌握JavaScript的异步编程,让你的代码更高效
在JavaScript中,异步编程是一种让应用程序在执行任务时不会阻塞主线程的编程范式。这意味着你的程序在等待长时间运行或外部操作完成的同时,仍然可以继续响应用户的交互并执行其他代码。这样做可以提高程序的响应速度和效率,尤其是在依赖大量网络请求、文件读写和用户交互的Web应用中,异步编程显得尤为重要。
前端达人
2024/11/25
2050
掌握JavaScript的异步编程,让你的代码更高效
相关推荐
37 - Async/Await : 简介​
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验