国外十大免费服务器和域名,搜索引擎优化的技巧有哪些,品牌策划方案怎么写,哪个网站可以做英语语法题TypeScript 中 await 的详解 1. 基本概念2. 语法要求3. 工作原理4. 与 Promise 的比较5. 实践中的注意事项总结 本文详细介绍了 TypeScript 中
await 的工作原理、语法要求、与 Promise 的关系以及实践中需要注意的问题#xff0c;同时针对代码示例进行了优化和补充说明。 1.… TypeScript 中 await 的详解 1. 基本概念2. 语法要求3. 工作原理4. 与 Promise 的比较5. 实践中的注意事项总结 本文详细介绍了 TypeScript 中
await 的工作原理、语法要求、与 Promise 的关系以及实践中需要注意的问题同时针对代码示例进行了优化和补充说明。 1. 基本概念 异步编程背景 传统异步编程常采用回调函数或 Promise 链式调用这容易导致“回调地狱”即指的是在处理异步操作时由于多个回调函数层层嵌套导致代码结构混乱、可读性差、难以维护和调试的现象。async/await 提供了类似同步代码的写法使逻辑更清晰便于调试和错误处理。 await 的作用 await 用于等待一个 Promise 的解析结果。当执行到 await 表达式时当前的 async 函数暂停执行直到等待的 Promise 进入 成功resolve 或 拒绝reject 状态然后继续执行后续代码。此外async 函数会自动捕获同步错误将其转换为返回 Promise 的拒绝状态。 async 函数返回值及状态变化 async 函数总是返回一个 Promise 如果函数返回一个非 Promise 值会等同于返回 Promise.resolve(值)如果函数内部抛出异常无论同步或异步错误返回的 Promise 则进入拒绝状态reject异常作为拒绝原因。 示例 async function getNumber() {return 42; // 等同于 return Promise.resolve(42)
}async function throwError() {throw new Error(失败); // 返回被拒绝的 Promise状态为 reject
}2. 语法要求 使用限制 await 只能在标记为 async 的函数内部使用否则会导致语法错误。例如 async function getData() {const response await fetch(https://api.example.com/data);return response.json();
}对非 Promise 值的处理 如果 await 后面的表达式不是一个 Promise执行时会直接返回该值等同于 await Promise.resolve(值)。例如 async function testNonPromise() {const result await 42; // 直接返回 42等同于 await Promise.resolve(42)console.log(result); // 输出 42
}
testNonPromise();对 thenable 对象的处理 如果表达式是一个具有 then 方法的对象则会按照 Promise 的规则处理。 3. 工作原理 暂停与状态机 当遇到 await 表达式时当前 async 函数会暂停执行其内部状态被保存。等待 Promise 解析后会恢复执行。在编译为 ES5 等低版本目标时TypeScript 会生成类似生成器函数的状态机代码通常借助 __awaiter 辅助函数实现。 非阻塞主线程 尽管 async 函数内部暂停执行但这不会阻塞 JavaScript 的事件循环主线程仍可响应其他任务。 错误处理 错误处理方式有两种 try/catch 捕获 可集中处理多个 await 操作中的错误适用于同步与异步错误均可捕获。 async function fetchData() {try {const response await fetch(https://api.example.com/data);if (!response.ok) throw new Error(请求失败);const data await response.json();console.log(data);} catch (error) {console.error(获取数据失败, error);}
}说明try/catch 块不仅能捕获 await 等待期间的异步错误还能捕获函数内部抛出的同步错误。 使用 .catch() 方法 可在单个 Promise 后直接捕获错误并返回默认值以便后续流程继续。 async function fetchDataWithCatch() {const response await fetch(https://api.example.com/data).catch(error {console.error(获取数据失败, error);return null;});if (response) {if (!response.ok) throw new Error(请求失败);const data await response.json();console.log(data);}
}4. 与 Promise 的比较 可读性提升 使用 async/await 使得代码逻辑看起来更接近同步流程避免了大量 .then() 的嵌套使错误处理更为集中。 编译转换细节 TypeScript 编译器会将 async/await 转换为基于 Promise 的实现。在目标环境为 ES5 或 ES6 时转换后的代码可能会借助 __awaiter 辅助函数或生成器函数实现状态机逻辑。例如 async function fetchData() {const result await fetch(https://api.example.com/data);if (!result.ok) throw new Error(请求失败);return await result.json();
}转换后相当于 function fetchData() {return __awaiter(this, void 0, void 0, function* () {const result yield fetch(https://api.example.com/data);if (!result.ok) throw new Error(请求失败);return yield result.json();});
}说明这里展示的转换逻辑只是示例具体实现依赖 TypeScript 版本和目标运行环境。 5. 实践中的注意事项 错误处理策略 对每个 await 操作都建议采用 try/catch 或在调用处使用 .catch() 来捕获错误确保程序健壮性。 例如 async function riskyOperation() {const response await fetch(https://api.example.com/data);if (!response.ok) throw new Error(请求失败);return response.json();
}riskyOperation().catch(error {console.error(外部捕获错误, error);
});并行与串行操作 对于多个互不依赖的异步操作若依次使用 await 会导致串行执行从而影响性能。建议使用 Promise.all 并行处理 async function fetchMultipleData() {const [data1, data2] await Promise.all([fetch(https://api.example.com/data1).then(res {if (!res.ok) throw new Error(data1 请求失败);return res.json();}),fetch(https://api.example.com/data2).then(res {if (!res.ok) throw new Error(data2 请求失败);return res.json();})]);console.log(data1, data2);
}若希望即使部分操作失败也能获得全部结果则可使用 Promise.allSettled async function fetchMultipleDataWithAllSettled() {const results await Promise.allSettled([fetch(https://api.example.com/data1).then(res res.json()),fetch(https://api.example.com/data2).then(res res.json())]);results.forEach(result {if (result.status fulfilled) {console.log(result.value);} else {console.error(失败原因, result.reason);}});
}说明在 Promise.allSettled 的示例中result.reason 类型为 any视情况可进行类型断言处理。 其他实践建议 HTTP 状态码检查建议对 fetch 返回的响应进行 response.ok 检查以确保请求成功循环中的 await当需要对异步迭代如读取流、异步生成器时可使用 for-await-of 循环top-level await在模块环境下ESM 模块TypeScript 也支持顶层 await但需要确保目标环境的兼容性术语统一文中统一使用“拒绝reject”描述 Promise 的拒绝状态 总结
通过使用 async/await我们可以编写出逻辑清晰、易于调试和维护的异步代码。关键要点包括
await 只能在 async 函数内使用async 函数返回 Promise内部的同步错误会转换为 Promise 的拒绝状态合理使用 try/catch 和 .catch() 进行错误处理对于多个互不依赖的异步操作建议采用并行执行方式如 Promise.all 或 Promise.allSettled以提升性能需注意 HTTP 响应状态码、循环中的异步处理以及 top-level await 的环境要求。
同时需要认识到async/await 并非完全替代 Promise而是对其进行封装和补充使得异步代码在语义和结构上更加直观。