• 主页

  • 投资

  • IT

    🔥
  • 设计

  • 销售

  • 共299篇

    前端 - Javascript

关闭

返回栏目

关闭

返回前端 - Javascript栏目

147 - async/await - async 函数 - async 函数的执行流程

作者:

贺及楼

成为作者

更新日期:2025-02-21 20:08:16

async/await - async 函数 - async 函数的执行流程

在 JavaScript 的异步编程领域,async/await 是一项强大且实用的特性。它构建在 Promise 的基础之上,为异步代码提供了一种更加简洁、直观的编写方式,让我们能够以同步代码的风格来处理异步操作。下面我们将深入探讨 async 函数及其执行流程。

什么是 async 函数

async 函数是一种特殊的函数,通过在 function 关键字前添加 async 关键字来定义。async 函数始终返回一个 Promise 对象,这个 Promise 对象的状态取决于函数内部的执行情况。如果函数内部正常返回一个值,该值会被包装成一个已解决(resolved)的 Promise;如果函数内部抛出异常,Promise 则会被拒绝(rejected)。

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

  1. async function exampleAsyncFunction() {
  2. return 'Hello, async!';
  3. }
  4. // 调用 async 函数
  5. const resultPromise = exampleAsyncFunction();
  6. resultPromise.then((result) => {
  7. console.log(result); // 输出: Hello, async!
  8. });

在这个例子中,exampleAsyncFunction 是一个 async 函数,它返回一个字符串。当我们调用这个函数时,实际上得到的是一个已解决的 Promise,其值就是函数返回的字符串。

await 关键字的作用

await 关键字只能在 async 函数内部使用,它的作用是暂停 async 函数的执行,直到其后面的 Promise 被解决(resolved 或 rejected),然后返回 Promise 的解决值。使用 await 可以让我们以同步代码的方式处理异步操作,避免了传统回调函数和 .then() 链式调用带来的代码嵌套问题。

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

  1. function delay(ms) {
  2. return new Promise((resolve) => {
  3. setTimeout(resolve, ms);
  4. });
  5. }
  6. async function exampleWithAwait() {
  7. console.log('Before await');
  8. await delay(2000); // 暂停 2 秒
  9. console.log('After await');
  10. return 'Done';
  11. }
  12. exampleWithAwait().then((result) => {
  13. console.log(result); // 输出: Done
  14. });

在这个例子中,exampleWithAwait 函数内部使用了 await 关键字来等待 delay 函数返回的 Promise 被解决。在 await 表达式执行时,函数会暂停执行,直到 delay 函数的定时器到期,Promise 被解决后,函数才会继续执行后续代码。

async 函数的执行流程

步骤概述

  1. 函数调用:当调用一个 async 函数时,函数会立即开始执行。
  2. 同步代码执行:函数内部的同步代码会按照顺序依次执行。
  3. 遇到 await:当遇到 await 表达式时,函数会暂停执行,并将控制权交还给调用者。await 后面的 Promise 会开始执行,函数会等待该 Promise 被解决。
  4. Promise 解决:当 await 后面的 Promise 被解决后,async 函数会从暂停的位置继续执行,await 表达式会返回 Promise 的解决值。
  5. 返回结果:如果函数内部没有更多的代码需要执行,或者遇到 return 语句,async 函数会返回一个 Promise,该 Promise 的状态取决于函数的执行情况。

示例分析

  1. function fetchData() {
  2. return new Promise((resolve) => {
  3. setTimeout(() => {
  4. resolve('Data fetched');
  5. }, 1000);
  6. });
  7. }
  8. async function main() {
  9. console.log('Step 1: Start main function');
  10. const data = await fetchData();
  11. console.log('Step 2: Data received:', data);
  12. return 'Function completed';
  13. }
  14. console.log('Before calling main');
  15. main().then((result) => {
  16. console.log('Step 3: Result:', result);
  17. });
  18. console.log('After calling main');

执行上述代码的输出顺序如下:

  1. Before calling main
  2. Step 1: Start main function
  3. After calling main
  4. // 等待 1 秒
  5. Step 2: Data received: Data fetched
  6. Step 3: Result: Function completed

执行流程解释

  1. 主程序开始:打印 Before calling main
  2. 调用 main 函数main 函数开始执行,打印 Step 1: Start main function
  3. 遇到 awaitmain 函数暂停执行,fetchData 函数返回的 Promise 开始执行,控制权交还给主程序。
  4. 主程序继续执行:打印 After calling main
  5. Promise 解决fetchData 函数的定时器到期,Promise 被解决,main 函数从暂停的位置继续执行,打印 Step 2: Data received: Data fetched
  6. 返回结果main 函数返回一个已解决的 Promise,其值为 Function completed,通过 .then() 方法打印 Step 3: Result: Function completed

总结

特性 描述
async 函数 始终返回一个 Promise 对象,函数内部的返回值会被包装成已解决的 Promise,抛出的异常会导致 Promise 被拒绝。
await 关键字 只能在 async 函数内部使用,用于暂停函数执行,等待 Promise 被解决,并返回 Promise 的解决值。
执行流程 调用 async 函数后,同步代码依次执行,遇到 await 暂停,Promise 解决后继续执行,最后返回 Promise。

async/await 为 JavaScript 异步编程提供了一种更加简洁、直观的方式,让我们能够以同步代码的风格处理异步操作,提高了代码的可读性和可维护性。通过深入理解 async 函数的执行流程,我们可以更好地运用这一特性来处理复杂的异步场景。