面试题答案
一键面试async/await 内部实现原理
- 基于 Generator 函数:
- Generator 函数是一种异步函数,它通过
yield
关键字暂停和恢复执行。例如:
function* gen() { yield 1; yield 2; return 3; } const g = gen(); console.log(g.next()); // { value: 1, done: false } console.log(g.next()); // { value: 2, done: false } console.log(g.next()); // { value: 3, done: true }
- async 函数本质上是 Generator 函数的语法糖,它自动将异步操作包装在 Promise 中。
async
函数内部的代码在遇到await
时,会暂停执行,就如同yield
暂停 Generator 函数一样。
- Generator 函数是一种异步函数,它通过
- 基于 Promise:
await
只能在async
函数内部使用,它等待一个 Promise 对象解决(resolved)或被拒绝(rejected)。当await
一个 Promise 时,async
函数的执行会暂停,直到该 Promise 被解决。例如:
async function asyncFunc() { const result = await Promise.resolve(42); return result; } asyncFunc().then(console.log); // 42
- 如果
await
的 Promise 被拒绝,async
函数会抛出错误,这可以通过try - catch
块捕获。例如:
async function asyncFunc() { try { const result = await Promise.reject(new Error('Error!')); } catch (error) { console.error('Caught error:', error.message); } } asyncFunc();
- 当
async
函数返回一个值时,这个值会被自动包装成已解决的 Promise。如果async
函数抛出错误,它会被包装成被拒绝的 Promise。
大型项目中优化 async/await 使用的策略
- 并行执行多个异步操作:
- 原理:使用
Promise.all
来并行执行多个async
操作。Promise.all
接受一个 Promise 数组作为参数,它返回一个新的 Promise,只有当所有输入的 Promise 都被解决时,这个新的 Promise 才会被解决;如果有任何一个 Promise 被拒绝,新的 Promise 就会被拒绝。例如:
async function fetchData1() { return new Promise(resolve => setTimeout(() => resolve('Data1'), 1000)); } async function fetchData2() { return new Promise(resolve => setTimeout(() => resolve('Data2'), 1500)); } async function main() { const [data1, data2] = await Promise.all([fetchData1(), fetchData2()]); console.log(data1, data2); } main();
- 优势:可以显著提高性能,因为多个异步操作不再按顺序执行,而是同时进行。在大型项目中,比如需要从多个 API 端点获取数据时,这种方式能减少整体的等待时间。
- 原理:使用
- 错误处理优化:
- 原理:在
async
函数中统一使用try - catch
块来处理错误,避免多个await
导致的重复错误处理代码。同时,可以封装一个错误处理函数,将错误处理逻辑集中起来。例如:
function handleError(error) { console.error('Global error handler:', error.message); } async function asyncFunc() { try { const result1 = await Promise.reject(new Error('Error in result1')); const result2 = await Promise.resolve('Result2'); } catch (error) { handleError(error); } } asyncFunc();
- 优势:提高代码的可维护性和可读性,在大型项目中,集中的错误处理使得错误追踪和修复更加容易,避免了在每个
await
处都重复编写类似的错误处理代码。
- 原理:在