(JavaScript)对 async/await 的理解

当涉及到 JavaScript 中的异步编程时,async/await 是一个强大而直观的工具,它使得处理异步代码更加容易理解和编写。让我们一步步地深入了解它。

1. 异步编程背景

在 JavaScript 中,某些操作可能需要一些时间来完成,比如网络请求、文件读取、定时器等。为了不阻塞程序的执行,JavaScript 使用了异步编程模型,即不等待某些操作完成,而是继续执行下面的代码。

2. Promise

在ES6中引入了 Promise 对象,用于更好地处理异步操作。但是,使用 Promise 仍然需要嵌套回调函数,导致代码可读性不佳,这就是所谓的"回调地狱"问题。

有关Promise的内容,可以看我对于promise的理解以及promise解决了什么问题这两个文章

3. async/await 的引入

为了解决回调地狱问题,ES2017(ES8)引入了 async/await。这是一种在写异步代码时更具可读性和可维护性的语法糖

什么是语法糖

"语法糖"是计算机科学中的一个概念,指的是一种在语言中添加的、对语言的语法结构进行改进,使得特定的代码模式更容易编写或更易于阅读的语法形式。语法糖并不引入新的功能,而是提供了一种更便捷、更易读的语法。

这个术语的意义在于,尽管它使得代码编写更加方便,但它本质上并没有改变语言的功能或能力。它只是一种语法层面上的改进,简化了代码的书写方式,使得开发者更容易理解和使用某些特性。

一个常见的例子是前文提到的 async/await,它被认为是 JavaScript 中的一种语法糖。使用 async/await 让异步代码看起来更像同步代码,但它本质上仍然是基于 Promise 的异步编程。

另一个例子是 Python 中的列表推导式。列表推导式提供了一种简洁的语法来创建列表,但实际上它是对常规循环的一种语法糖。

总的来说,语法糖是一种为了提高代码可读性和编写效率而引入的语法结构。

4. async 函数

async 关键字用于定义一个返回 Promise 的异步函数。使用 async 声明的函数内部,可以使用 await 关键字来暂停函数执行,等待 Promise 解决,语法上强制规定 await 只能出现在 asnyc 函数中

javascript 复制代码
async function fetchData() {
  // 异步操作,比如请求数据
  let result = await fetchDataFromServer();
  console.log(result);
}

5. await 表达式

await 只能async 函数内部使用,用于等待一个表达式解决为 Promise。当 await 后面的表达式被解决时,它返回解决的值。

javascript 复制代码
async function fetchData() {
  let result = await fetchDataFromServer();
  console.log(result);
}

// fetchDataFromServer 返回一个 Promise
function fetchDataFromServer() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve("Data fetched successfully!");
    }, 2000);
  });
}

// 使用
fetchData();

6. 错误处理

使用 try/catch 来处理异步函数中的错误,这比传统的回调错误处理更为直观

javascript 复制代码
async function fetchData() {
  try {
    let result = await fetchDataFromServer();
    console.log(result);
  } catch (error) {
    console.error("Error fetching data:", error);
  }
}

7. 同步化的写法

async/await 使得异步代码的写法更类似于同步代码,提高了代码的可读性和可维护性。

javascript 复制代码
async function fetchDataSequentially() {
  let result1 = await fetchDataFromServer1();
  console.log(result1);

  let result2 = await fetchDataFromServer2();
  console.log(result2);

  // ...
}

8.一些有关概念

  1. 返回 Promise 对象: async函数总是返回一个Promise对象。这是因为async函数内部使用Promise.resolve()来封装函数返回的值。无论async函数返回的是一个直接量还是一个经过Promise.resolve()包装的值,最终都会被封装成一个Promise对象。

    javascript 复制代码
    async function exampleAsyncFunction() {
      return 42;
    }
    
    const resultPromise = exampleAsyncFunction();
    console.log(resultPromise); // Promise { 42 }
  2. 无返回值情况: 如果async函数没有显式的return语句,或者return的是一个没有使用await关键字的表达式,那么该async函数会隐式返回Promise.resolve(undefined)

    javascript 复制代码
    async function exampleAsyncFunction() {
      // 没有 return 或者 return 后没有使用 await
    }
    
    const resultPromise = exampleAsyncFunction();
    console.log(resultPromise); // Promise { undefined }
  3. 无等待立即执行: 在没有await的情况下执行async函数时,它会立即执行并返回一个Promise对象。这是因为async函数内部的代码会立即执行,不会等待异步操作完成。

    javascript 复制代码
    async function exampleAsyncFunction() {
      console.log("Async function is executing");
      return 42;
    }
    
    const resultPromise = exampleAsyncFunction();
    console.log(resultPromise); // Promise { 42 }
  4. Promise.resolve(x)的简写: Promise.resolve(x)是一个用于快速将值x封装成Promise对象的方法。它是Promise构造函数的一个静态方法。你可以把它看作是new Promise(resolve => resolve(x))的简写形式,用于将字面量对象或其他对象封装成Promise实例。

    javascript 复制代码
    const value = 42;
    const promise = Promise.resolve(value);
    console.log(promise); // Promise { 42 }

总结

async/await 是 JavaScript 异步编程的一个巨大进步,使得异步代码更易于编写和理解。通过使异步代码看起来像同步代码,它提高了可读性,同时保留了异步编程的非阻塞特性。

相关推荐
EasyNTS41 分钟前
H.264/H.265播放器EasyPlayer.js视频流媒体播放器关于websocket1006的异常断连
javascript·h.265·h.264
活宝小娜2 小时前
vue不刷新浏览器更新页面的方法
前端·javascript·vue.js
程序视点2 小时前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
coldriversnow2 小时前
在Vue中,vue document.onkeydown 无效
前端·javascript·vue.js
我开心就好o2 小时前
uniapp点左上角返回键, 重复来回跳转的问题 解决方案
前端·javascript·uni-app
开心工作室_kaic3 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
刚刚好ā3 小时前
js作用域超全介绍--全局作用域、局部作用、块级作用域
前端·javascript·vue.js·vue
沉默璇年4 小时前
react中useMemo的使用场景
前端·react.js·前端框架
yqcoder5 小时前
reactflow 中 useNodesState 模块作用
开发语言·前端·javascript
2401_882727575 小时前
BY组态-低代码web可视化组件
前端·后端·物联网·低代码·数学建模·前端框架