盘点JavaScript中Async/Await知识

开发 前端
Async/await 是以更舒适的方式使用 promise 的一种特殊语法,同时它也非常易于理解和使用。

[[412197]]

大家好,我是进阶学习者。

一、前言

Async/await 是以更舒适的方式使用 promise 的一种特殊语法,同时它也非常易于理解和使用。

二、Async function

让以 async 这个关键字开始。它可以被放置在一个函数前面。

如下所示:

  1. async function f() { 
  2.   return 1; 

在函数前面的 “async” 这个单词表达了一个简单的事情:即这个函数总是返回一个 promise。其他值将自动被包装在一个 resolved 的 promise 中。

例如,下面这个函数返回一个结果为 1 的 resolved promise。

让测试一下:

  1. async function f() { 
  2.   return 1; 
  3. f().then(alert); // 1 

也可以显式地返回一个 promise,结果是一样的:

  1. async function f() { 
  2.   return Promise.resolve(1); 
  3. f().then(alert); // 1 

注:

async 确保了函数返回一个 promise,也会将非 promise 的值包装进去。很简单,对吧?但不仅仅这些。还有另外一个叫 await 的关键词,它只在 async 函数内工作,也非常酷。

三、Await

1. 语法

  1. // 只在 async 函数内工作 
  2. let value = await promise; 

关键字 await 让 JavaScript 引擎等待直到 promise 完成(settle)并返回结果。

这里的例就是一个 1 秒后 resolve 的 promise:

  1. async function f() { 
  2.   let promise = new Promise((resolve, reject) => { 
  3.     setTimeout(() => resolve("done!"), 1000) 
  4.   }); 
  5.   let result = await promise; // 等待,直到 promise resolve (*) 
  6.   alert(result); // "done!" 
  7. f(); 

代码解析:

这个函数在执行的时候,“暂停”在了 (*) 那一行,并在 promise settle 时,拿到 result 作为结果继续往下执行。所以上面这段代码在一秒后显示 “done!”。

await 字面的意思就是让 JavaScript 引擎等待直到 promise settle,然后以 promise 的结果继续执行。这个行为不会耗费任何 CPU 资源,因为引擎可以同时处理其他任务:执行其他脚本,处理事件等。

相比于 promise.then,它只是获取 promise 的结果的一个更优雅的语法,同时也更易于读写。

不能在普通函数中使用 await。

如果尝试在非 async 函数中使用 await 的话,就会报语法错误:

  1. function f() { 
  2.   let promise = Promise.resolve(1); 
  3.   let result = await promise; // Syntax error 

如果函数前面没有 async 关键字,就会得到一个语法错误。就像前面说的,await 只在 async 函数 中有效。

showAvatar() 例子,并将其改写成 async/await 的形式:

需要用 await 替换掉 .then 的调用。

另外,需要在函数前面加上 async 关键字,以使它们能工作。

  1. async function showAvatar() { 
  2.   // 读取的 JSON 
  3.   let response = await fetch('/article/promise-chaining/user.json'); 
  4.   let user = await response.json(); 
  5.   // 读取 github 用户信息 
  6.   let githubResponse = await fetch(`https://api.github.com/users/${user.name}`); 
  7.   let githubUser = await githubResponse.json(); 
  8.   // 显示头像 
  9.   let img = document.createElement('img'); 
  10.   img.src = githubUser.avatar_url; 
  11.   img.className = "promise-avatar-example"
  12.   document.body.append(img); 
  13.   // 等待 3 秒 
  14.   await new Promise((resolve, reject) => setTimeout(resolve, 3000)); 
  15.   img.remove(); 
  16.   return githubUser; 
  17. showAvatar(); 

简洁明了,是吧?比之前可强多了。await 不能在顶层代码运行。

这有一个用于演示的 Thenable 类

下面的 await 接受了该类的例子:

  1. class Thenable { 
  2.   constructor(num) { 
  3.     this.num = num; 
  4.   } 
  5.   then(resolve, reject) { 
  6.     alert(resolve); 
  7.     // 1000ms 后使用 this.num*2 进行 resolve 
  8.     setTimeout(() => resolve(this.num * 2), 1000); // (*) 
  9.   } 
  10. }; 
  11. async function f() { 
  12.   // 等待 1 秒,之后 result 变为 2 
  13.   let result = await new Thenable(1); 
  14.   alert(result); 
  15. f(); 

运行结果:

注:

如果 await 接收了一个非 promise 的但是提供了 .then 方法的对象,它就会调用这个 .then 方法,并将内建的函数 resolve 和 reject 作为参数传入(就像它对待一个常规的 Promise executor 时一样)。

然后 await 等待直到这两个函数中的某个被调用(在上面这个例子中发生在 (*) 行),然后使用得到的结果继续执行后续任务。

2. Class 中的 async 方法

要声明一个 class 中的 async 方法,只需在对应方法前面加上 async 即可:

  1. class Waiter { 
  2.   async wait() { 
  3.     return await Promise.resolve(1); 
  4.   } 
  5. new Waiter() 
  6.   .wait() 
  7.   .then(alert); // 1 

运行结果:

注:

它确保了方法的返回值是一个 promise 并且可以在方法中使用 await。

四、总结

本文基于JavaScript基础,介绍了async的使用。函数前面的关键字 async 有两个作用:让这个函数总是返回一个 promise。允许在该函数内使用 await。

这两个关键字一起提供了一个很好的用来编写异步代码的框架,这种代码易于阅读也易于编写。通过案例的分分析,图文结合的方式,进行详细的讲解,使用JavaScript语言,能够让读者更好的理解。 

代码很简单,希望能够帮助你更好的学习。

 

责任编辑:武晓燕 来源: 前端进阶学习交流
相关推荐

2016-11-22 11:08:34

asyncjavascript

2021-06-07 09:44:10

JavaScript开发代码

2021-06-28 08:10:59

JavaScript异步编程

2014-07-15 10:31:07

asyncawait

2022-11-21 09:01:00

Swift并发结构

2021-08-30 10:25:48

JavaScript进阶操作前端

2021-08-26 10:25:04

JavaScript进阶操作 前端

2012-07-22 15:59:42

Silverlight

2023-10-08 10:21:11

JavaScriptAsync

2017-06-19 09:12:08

JavaScriptPromiseAsync

2022-08-27 13:49:36

ES7promiseresolve

2023-07-28 07:31:52

JavaScriptasyncawait

2021-06-28 07:27:43

AwaitAsync语法

2021-06-15 05:36:45

Gulpawaitasync

2022-06-13 07:36:47

useEffectHooks

2017-04-10 15:57:10

AsyncAwaitPromise

2022-06-16 10:37:09

asyncawait

2020-06-02 10:09:59

JavaScript开发 可视化

2017-02-20 23:05:14

JavaScript

2017-08-02 14:17:08

前端asyncawait
点赞
收藏

51CTO技术栈公众号