Promise是异步编程核心,通过状态机和链式调用解决回调地狱;其原理包括状态管理、then方法返回新Promise及resolvePromise处理返回值,实现异步任务的有序执行与错误捕获。

JavaScript是单线程语言,为了不阻塞主线程,异步操作成为处理耗时任务(如网络请求、文件读取)的核心机制。早期通过回调函数实现异步,但容易陷入“回调地狱”。ES6引入的Promise极大改善了这一问题。本文将深入剖析Promise的实现原理,帮助你真正理解其工作机制。
Promise 是一个表示异步操作最终完成或失败的对象。它有三种状态:
一旦状态从 pending 变为 fulfilled 或 rejected,就不会再改变,且这个结果可以被后续通过 then 方法注册的回调函数获取。
要理解原理,最好的方式是自己实现一个简化版的 Promise。我们称之为 MyPromise。
立即学习“Java免费学习笔记(深入)”;
function MyPromise(executor) {
let self = this;
self.status = 'pending'; // 初始状态
self.value = undefined; // 成功时的值
self.reason = undefined; // 失败时的原因
self.onResolvedCallbacks = []; // 存储成功的回调
self.onRejectedCallbacks = []; // 存储失败的回调
function resolve(value) {
if (self.status === 'pending') {
self.status = 'fulfilled';
self.value = value;
self.onResolvedCallbacks.forEach(fn => fn());
}
}
function reject(reason) {
if (self.status === 'pending') {
self.status = 'rejected';
self.reason = reason;
self.onRejectedCallbacks.forEach(fn => fn());
}
}
// 立即执行 executor 函数
try {
executor(resolve, reject);
} catch (err) {
reject(err); // 如果执行出错,直接进入 reject
}
}
上面代码定义了 MyPromise 构造函数,接收一个 executor 函数,并立即执行它。resolve 和 reject 用于改变状态并通知所有监听者。
then 是 Promise 的核心方法,用于注册成功和失败的回调,并支持链式调用。
MyPromise.prototype.then = function(onFulfilled, onRejected) {
let self = this;
// 解决 onFulfilled、onRejected 不传的情况
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val;
onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err; };
// 返回一个新的 Promise,实现链式调用
let promise2 = new MyPromise((resolve, reject) => {
if (self.status === 'fulfilled') {
setTimeout(() => {
try {
let x = onFulfilled(self.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
}
if (self.status === 'rejected') {
setTimeout(() => {
try {
let x = onRejected(self.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
}
if (self.status === 'pending') {
// 如果状态还未改变,说明异步操作未完成,先存储回调
self.onResolvedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onFulfilled(self.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
self.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onRejected(self.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
}
});
return promise2;
};
关键点:
这是 Promise/A+ 规范中最复杂的一部分。它决定如何根据 then 回调的返回值 x 来处理下一个 Promise 的状态。
function resolvePromise(promise2, x, resolve, reject) {
// 防止循环引用
if (x === promise2) {
return reject(new TypeError('Chaining cycle detected for promise'));
}
let called = false; // 确保只调用一次 resolve 或 reject
// 如果 x 是对象或函数,才可能是 Promise
if (x != null && (typeof x === 'object' || typeof x === 'function')) {
try {
let then = x.then;
// 如果 x 是 Promise,则采用它的状态
if (typeof then === 'function') {
then.call(x, y => {
if (called) return;
called = true;
resolvePromise(promise2, y, resolve, reject); // 递归解析
}, r => {
if (called) return;
called = true;
reject(r);
});
} else {
// x 是普通对象
resolve(x);
}
} catch (e) {
if (called) return;
called = true;
reject(e);
}
} else {
// x 是基本类型值
resolve(x);
}
}
该函数处理了各种情况:普通值、Promise、具有 then 方法的“类Promise”对象等,确保符合 Promise/A+ 规范。
原生 Promise 提供了一些常用静态方法,也可以简单实现:
// MyPromise.resolve
MyPromise.resolve = function(value) {
return new MyPromise(resolve => resolve(value));
};
// MyPromise.reject
MyPromise.reject = function(reason) {
return new MyPromise((resolve, reject) => reject(reason));
};
// MyPromise.all
MyPromise.all = function(promises) {
return new MyPromise((resolve, reject) => {
let result = [];
let count = 0;
if (promises.length === 0) return resolve(result);
for (let i = 0; i < promises.length; i++) {
MyPromise.resolve(promises[i]).then(
val => {
result[i] = val;
count++;
if (count === promises.length) {
resolve(result);
}
},
err => reject(err)
);
}
});
};
这些方法极大提升了异步编程的表达能力。
基本上就这些。虽然完整实现一个符合规范的 Promise 还涉及更多边界处理,但核心逻辑已经清晰。理解 Promise 的实现原理,不仅能写出更可靠的异步代码,也为学习 async/await 打下坚实基础。
以上就是JavaScript异步编程_全面剖析Promise实现原理的详细内容,更多请关注php中文网其它相关文章!
编程怎么学习?编程怎么入门?编程在哪学?编程怎么学才快?不用担心,这里为大家提供了编程速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号