async/await工作原理
搞懂 Promise
async/await 是 Promise 的语法糖,所以得先知道 Promise 是什么。
Promise 本质上就是一个状态机,三种状态:
pending:等待中
fulfilled:成功了
rejected:失败了
状态只能从 pending 变成另外两种,而且不可逆。
const p = new Promise((resolve, reject) => {
setTimeout(() => resolve('done'), 1000);
});
p.then(result => console.log(result)); // 1秒后打印 "done"事件循环
要理解 async/await,必须知道事件循环(Event Loop)。
JavaScript 的执行模型大概是这样:
调用栈(Call Stack)
↓ 同步代码在这里执行
微任务队列(Microtask Queue)
↓ Promise.then、queueMicrotask 等
宏任务队列(Macrotask Queue)
↓ setTimeout、setInterval、I/O 等async/await 的真面目
async 函数本质上是一个返回 Promise 的函数。
async function foo() {
return 42;
}
// 等价于
function foo() {
return Promise.resolve(42);
}await 则是暂停当前 async 函数的执行,等 Promise 完成后再继续。
用伪代码理解:
async function fetchUser() {
const res = await fetch('/api/user');
const data = await res.json();
return data;
}
// 大概等价于
function fetchUser() {
return fetch('/api/user').then(res => {
return res.json().then(data => {
return data;
});
});
}错误处理
async/await 的错误处理比 Promise 链直观很多:
// Promise 链写法
fetch('/api/user')
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
// async/await 写法
async function fetchUser() {
try {
const res = await fetch('/api/user');
const data = await res.json();
console.log(data);
} catch (err) {
console.error(err);
}
}手写一个 Promise
class MyPromise {
constructor(executor) {
this.state = 'pending';
this.value = undefined;
this.callbacks = []; // 存放 then 注册的回调
const resolve = (value) => {
if (this.state !== 'pending') return;
this.state = 'fulfilled';
this.value = value;
// 通知所有等待的回调
this.callbacks.forEach(cb => cb.onFulfilled(value));
};
const reject = (reason) => {
if (this.state !== 'pending') return;
this.state = 'rejected';
this.value = reason;
this.callbacks.forEach(cb => cb.onRejected(reason));
};
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
then(onFulfilled, onRejected) {
// 返回新的 Promise,支持链式调用
return new MyPromise((resolve, reject) => {
const handle = (fn, val) => {
// 用 queueMicrotask 模拟微任务
queueMicrotask(() => {
try {
const result = fn(val);
// 如果返回的也是 Promise,等它完成
if (result instanceof MyPromise) {
result.then(resolve, reject);
} else {
resolve(result);
}
} catch (err) {
reject(err);
}
});
};
if (this.state === 'fulfilled') {
handle(onFulfilled, this.value);
} else if (this.state === 'rejected') {
handle(onRejected, this.value);
} else {
// 还在 pending,先存起来等 resolve/reject 触发
this.callbacks.push({
onFulfilled: val => handle(onFulfilled, val),
onRejected: val => handle(onRejected, val),
});
}
});
}
catch(onRejected) {
return this.then(null, onRejected);
}
static resolve(value) {
return new MyPromise(resolve => resolve(value));
}
static reject(reason) {
return new MyPromise((_, reject) => reject(reason));
}
}async/await工作原理
http://localhost:8090/archives/async-awaitgong-zuo-yuan-li