await

await

await 操作符用于等待一个Promise 对象。它只能在异步函数 async function 中使用。

语法

[返回值] = await 表达式;

表达式

一个 Promise 对象或者任何要等待的值。

返回值

返回 Promise 对象的处理结果。如果等待的不是 Promise 对象,则返回该值本身。

描述

await 表达式会暂停当前 async function 的执行,等待 Promise 处理完成。若 Promise 正常处理(fulfilled),其回调的resolve函数参数作为 await 表达式的值,继续执行 async function

若 Promise 处理异常(rejected),await 表达式会把 Promise 的异常原因抛出。

另外,如果 await 操作符后的表达式的值不是一个 Promise,则返回该值本身。

例子

如果一个 Promise 被传递给一个 await 操作符,await 将等待 Promise 正常处理完成并返回其处理结果。

function resolveAfter2Seconds(x) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(x);
    }, 2000);
  });
}

async function f1() {
  var x = await resolveAfter2Seconds(10);
  console.log(x); // 10
}
f1();

如果该值不是一个 Promise,await 会把该值转换为已正常处理的Promise,然后等待其处理结果。

async function f2() {
  var y = await 20;
  console.log(y); // 20
}
f2();

如果 Promise 处理异常,则异常值被抛出。

async function f3() {
  try {
    var z = await Promise.reject(30);
  } catch (e) {
    console.log(e); // 30
  }
}
f3();

摘抄文档MDN

### Await 异步编程用法及常见问题 异步编程是现代编程中处理耗时操作(如网络请求、文件读写等)的核心技术之一。`async` 和 `await` 是实现异步编程的一种简洁方式,它们使异步代码的编写和阅读更加直观。以下是关于 `await` 的详细用法及常见问题的解答。 #### 1. 基本用法 `await` 关键字用于等待一个异步操作完成,它只能在标记为 `async` 的函数中使用。当执行到 `await` 表达式时,程序会暂停当前函数的执行,直到等待的异步操作完成,然后继续执行后续代码[^1]。 ```javascript async function fetchData() { try { const response = await fetch('https://api.example.com/data'); // 等待网络请求完成 const data = await response.json(); // 等待解析 JSON 完成 console.log(data); } catch (error) { console.error('Error fetching data:', error); } } ``` #### 2. 常见问题及解决方案 ##### 问题 1: `async` 函数中没有 `await` 表达式 如果一个函数被标记为 `async`,但其中没有任何 `await` 表达式,则该函数会像同步函数一样执行。尽管如此,编译器通常会发出警告以提示开发者这种潜在的误用。 ```javascript async function example() { console.log('This function is async but contains no await.'); } example(); // 输出: This function is async but contains no await. ``` ##### 问题 2: 异步编程是否创建新线程 异步编程本质上并不意味着多线程。虽然某些异步操作可能会在后台线程中运行(例如 I/O 操作),但 `async` 函数本身不会直接启动新线程。实际上,`async` 函数中的代码仍然在调用线程中执行,直到遇到 `await` 表达式才会暂停[^2]。 ```javascript async function example() { console.log('Start'); await new Promise(resolve => setTimeout(resolve, 1000)); // 模拟耗时操作 console.log('End after 1 second'); } example(); console.log('This will execute immediately.'); ``` ##### 问题 3: `await` 后未正确处理返回值或异常 当使用 `Task.WhenAny` 或类似方法时,必须注意 `await` 的对象并不是最终结果,而是另一个 `Task` 对象。因此需要再次 `await` 来获取实际结果或确保异常被抛出[^3]。 ```csharp var task1 = Task.Delay(1000).ContinueWith(t => "Result from Task 1"); var task2 = Task.Delay(2000).ContinueWith(t => "Result from Task 2"); var finishedTask = await Task.WhenAny(task1, task2); // 等待任一任务完成 var result = await finishedTask; // 再次等待以获取实际结果 Console.WriteLine(result); ``` ##### 问题 4: 错误处理 `try-catch` 结构可以捕获由 `await` 表达式引发的异常,从而简化错误处理逻辑。此外,与传统的 `Promise` 链相比,`async/await` 提供了更清晰的错误处理机制[^4]。 ```javascript async function fetchData() { try { const response = await fetch('https://api.example.com/nonexistent'); if (!response.ok) throw new Error('Network response was not ok'); const data = await response.json(); console.log(data); } catch (error) { console.error('Error:', error.message); } } ``` #### 3. 优势与局限性 - **优势**: - 异步代码的结构类似于同步代码,避免了 `Promise` 链接嵌套的问题。 - 使用 `try-catch` 可同时处理同步和异步错误,提升了调试效率。 - **局限性**: - 如果不正确地使用 `await`,可能导致性能问题,例如不必要的阻塞。 - 在某些框架(如 Flutter)中,可能需要额外的方法来处理异步任务的结果[^5]。 ```dart Future<void> fetchData() async { try { final response = await http.get(Uri.parse('https://api.example.com/data')); if (response.statusCode == 200) { print('Data fetched successfully'); } else { throw Exception('Failed to load data'); } } on Exception catch (e) { print('Error: $e'); } } ``` #### 4. 最佳实践 - 总是将 `async` 和 `await` 配对使用,避免在非异步上下文中误用 `await`。 - 在处理多个异步任务时,考虑使用 `Promise.all` 或 `Task.WhenAll` 等方法以提高效率。 - 确保所有可能的异常都被适当捕获并处理。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值