从Promise到async/await:手写实现异步编程核心机制全解析
2025.09.19 12:47浏览量:0简介:本文深入解析异步编程核心机制,通过手写实现Promise全家桶、Generator及async/await,揭示其底层原理与协作关系。从基础Promise到高级语法,逐步构建完整的异步控制体系,帮助开发者彻底掌握JavaScript异步编程精髓。
一、Promise核心机制手写实现
1.1 Promise基础结构
Promise本质是一个具有状态的特殊对象,包含三种状态转换逻辑:
class MyPromise {
constructor(executor) {
this.state = 'pending'; // pending/fulfilled/rejected
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
this.onFulfilledCallbacks.forEach(fn => fn());
}
};
const reject = (reason) => {
if (this.state === 'pending') {
this.state = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn());
}
};
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
}
关键设计点:
- 状态机模型:严格限制状态单向转换
- 异步回调队列:解决then方法调用时机问题
- 错误捕获机制:通过try-catch统一处理执行器错误
1.2 then方法链式调用实现
then(onFulfilled, onRejected) {
// 参数默认值处理
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };
const promise2 = new MyPromise((resolve, reject) => {
if (this.state === 'fulfilled') {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else if (this.state === 'rejected') {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else if (this.state === 'pending') {
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
}
});
return promise2;
}
实现要点:
- 微任务队列模拟:使用setTimeout模拟异步调度
- 值穿透处理:非函数参数直接透传值
- 返回值解析:通过resolvePromise处理thenable对象
1.3 静态方法实现
// 全局resolve方法
static resolve(value) {
if (value instanceof MyPromise) {
return value;
}
return new MyPromise(resolve => resolve(value));
}
// 全局reject方法
static reject(reason) {
return new MyPromise((_, reject) => reject(reason));
}
// 全局all方法
static all(promises) {
return new MyPromise((resolve, reject) => {
const results = [];
let count = 0;
const processValue = (index, value) => {
results[index] = value;
count++;
if (count === promises.length) {
resolve(results);
}
};
promises.forEach((promise, index) => {
if (promise instanceof MyPromise) {
promise.then(
value => processValue(index, value),
reason => reject(reason)
);
} else {
processValue(index, promise);
}
});
});
}
二、Generator函数实现原理
2.1 生成器基础结构
function* myGenerator() {
yield 1;
yield 2;
return 3;
}
// 手写生成器迭代器
class Generator {
constructor(generatorFn) {
this.generatorFn = generatorFn;
this.context = {};
this.step = null;
this.init();
}
init() {
this.step = this.generatorFn.call(this.context);
}
next(value) {
const result = this.step.next(value);
if (!result.done) {
// 保存当前执行位置
this.step = result.value;
}
return result;
}
[Symbol.iterator]() {
return this;
}
}
核心机制:
- 状态保存:通过闭包保存执行上下文
- 迭代协议:实现next方法返回{value, done}对象
- 协程模型:yield表达式暂停执行
2.2 自动执行器实现
function co(generatorFn) {
return new Promise((resolve, reject) => {
const gen = generatorFn();
function step(nextFn) {
let result;
try {
result = nextFn();
} catch (err) {
return reject(err);
}
if (result.done) {
return resolve(result.value);
}
Promise.resolve(result.value).then(
value => step(() => gen.next(value)),
reason => step(() => gen.throw(reason))
);
}
step(() => gen.next());
});
}
执行流程:
- 初始化生成器
- 递归执行next/throw方法
- 自动处理Promise链式调用
- 最终结果透传
三、async/await编译原理
3.1 语法糖转换
async函数本质是Generator函数的语法糖,Babel转换示例:
// 源码
async function fetchData() {
const res = await fetch('/api');
return res.json();
}
// 转换后
function fetchData() {
return regeneratorRuntime.async(function fetchData$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return regeneratorRuntime.awrap(fetch('/api'));
case 2:
res = _context.sent;
return _context.abrupt('return', res.json());
case 4:
case 'end':
return _context.stop();
}
}
}, null, this);
}
关键转换点:
- async函数转换为Generator函数
- await表达式转换为yield表达式
- 自动添加执行器逻辑
3.2 运行时支持
regeneratorRuntime核心方法:
const regeneratorRuntime = {
async(generatorFn, receiver, thisArg) {
return new Promise((resolve, reject) => {
const generator = generatorFn.apply(thisArg, [receiver]);
function handle(result) {
if (result.done) {
resolve(result.value);
} else {
Promise.resolve(result.value).then(
value => handle(generator.next(value)),
reason => {
try {
handle(generator.throw(reason));
} catch (err) {
reject(err);
}
}
);
}
}
handle(generator.next());
});
},
awrap(promise) {
return { __await: promise };
}
};
四、异步编程最佳实践
4.1 Promise组合技巧
// 并发控制
function limitConcurrency(promises, limit) {
return new Promise((resolve, reject) => {
const results = [];
let index = 0;
let resolving = 0;
function execute() {
if (index >= promises.length && resolving === 0) {
return resolve(results);
}
while (resolving < limit && index < promises.length) {
resolving++;
const currentIndex = index++;
Promise.resolve(promises[currentIndex]())
.then(result => {
results[currentIndex] = result;
})
.catch(reject)
.finally(() => {
resolving--;
execute();
});
}
}
execute();
});
}
4.2 错误处理模式
// 集中式错误处理
async function safeExecute(asyncFn) {
try {
return { success: true, data: await asyncFn() };
} catch (error) {
return { success: false, error };
}
}
// 链式错误恢复
function retry(fn, times) {
return new Promise((resolve, reject) => {
function attempt() {
Promise.resolve(fn())
.then(resolve)
.catch((err) => {
if (times-- <= 0) {
reject(err);
} else {
attempt();
}
});
}
attempt();
});
}
4.3 性能优化建议
- 避免Promise嵌套:使用扁平化链式调用
- 合理使用缓存:对重复请求结果进行缓存
- 资源释放:及时取消不再需要的请求
- 批量处理:合并多个小请求为大请求
五、完整实现示例
// 完整Promise实现
class CompletePromise {
// ...前文Promise实现代码...
}
// 添加catch方法
CompletePromise.prototype.catch = function(onRejected) {
return this.then(null, onRejected);
};
// 添加finally方法
CompletePromise.prototype.finally = function(callback) {
return this.then(
value => CompletePromise.resolve(callback()).then(() => value),
reason => CompletePromise.resolve(callback()).then(() => { throw reason })
);
};
// 测试用例
const promise = new CompletePromise((resolve) => {
setTimeout(() => resolve('Success'), 1000);
});
promise
.then(res => {
console.log(res); // Success
return new CompletePromise(resolve => resolve('Nested'));
})
.then(res => console.log(res)) // Nested
.catch(err => console.error(err))
.finally(() => console.log('Completed'));
六、总结与展望
实现要点总结:
- Promise核心是状态机+异步回调队列
- Generator通过yield实现协程控制
- async/await是Generator的语法糖封装
应用场景选择:
- 简单异步:Promise直接使用
- 复杂流程:Generator+co组合
- 现代开发:优先使用async/await
未来演进方向:
- 结合Observables处理流式数据
- 与Web Workers的异步集成
- 更精细的并发控制机制
通过手写实现这些核心机制,开发者不仅能深入理解JavaScript异步编程原理,还能在实际开发中更灵活地运用这些技术,编写出更健壮、高效的异步代码。
发表评论
登录后可评论,请前往 登录 或 注册