用法 😏
let p = new Promise((resolve, reject) => {
if (success) resolve('ok')
else reject('error')
})
p.then(
res => console.log('成功', res),
err => console.log('失败', err)
)
.catch(err => console.log('失败', err))
.finally(() => console.log('无论成功失败都执行'))
Promise.resolve('ok')
Promise.reject('error')
Promise.all([p1, p2, p3]).then(res => {
// res 每个 promise 的结果组成的数组
})
Promise.race([p1, p2, p3]).then(res => {
// 最早完成的 promise 的结果
})
原理 😊
Promise
的状态只能从pending => resolved
或 从pending => rejected
,状态一旦改变不会再变- 要创建一个
Promise
对象,需要new Promise(executor)
,并传入一个executor
,该函数默认有两个方法参数(resolve, reject
),在executor
内执行用户逻辑(异步或同步代码),执行完根据成功/失败情况调用resolve/reject
Promise
会根据Promise
对象当前的状态决定走.then
中的onFullfilled/onRejected
(用户传入的成功处理函数、失败处理函数)Promise
对象可以无限.then
则代表每次返回的都是一个新的Promise
对象,每个.then
函数返回的data
都会作为下一个.then
函数的参数
基本实现 👩🏻💻
const PENDING = 'PENDING'
const RESOLVED = 'RESOLVED'
const REJECTED = 'REJECTED'
class Promise {
constructor(executor) {
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
// resolve 方法,将 Promise 对象的状态改变为成功,并将成功值赋给 value 供给 .then方法的 onFullfilled 使用
let resolve = (value) => {
if (this.status === PENDING) {
this.status = RESOLVED;
this.value = value;
}
}
// reject 方法,将 Promise 对象的状态改变未失败,并将失败值赋给 reason 供给 .then 方法的 onRejected 使用
let reject = (reason) => {
if (this.status === PENDING) {
this.status = REJECTED;
this.reason = reason;
}
}
// 捕获同步代码产生的错误
try {
executor(resolve, reject);
} catch(e) {
reject(err)
}
}
// Promise 实例的 then 方法
then(onFullfilled, onRejected) {
// 如果状态是 成功态,执行 成功的回调
if (this.status === RESOLVED) {
onFullfilled(this.value)
}
// 如果状态是 失败态,执行 失败的回调
if (this.status === REJECTED) {
onRejected(this.reason)
}
}
}
到这里实现了最基本的状态变更、数据存储及成功或失败的回调调用,使用一下
let p = new Promise((resolve, reject) => {
resolve('ok')
})
p.then(res => console.log('成功', res)) // 成功ok
加强 🔨
Promise
中的 executor
支持异步逻辑,即resolve/reject
并不是立即调用
// 增加异步时回调的存储
class Promise {
constructor(props) {
// ...
this.onFullfilledCallbacks = []; // 存储成功回调
this.onRejectedCallbacks = []; // 存储失败回调
let resolve = (value) => {
// ... 修改状态,存储 value 值
// 依次执行存储的回调函数
// 如果 resolve 的 value 是 Promise,则执行 .then 取到最终值再返回
if (value instanceof Promise) {
return value.then(resolve, reject)
}
this.onFullfilledCallbacks.forEach(fn => fn());
}
let reject = (reason) => {
// ...
this.onRejectedCallbacks.forEach(fn => fn());
}
}
then(onFullfilled, onRejected) {
// ...
// 如果是异步,未立即修改 Promise 对象的状态,存储用户传入的成功、失败回调函数,
if (this.status === PENDING) {
this.onFullfilledCallbacks.push(() => {
// aop 切面思想,预留处理其它问题
onFullfilled(this.value)
})
this.onRejectedCallbacks.push(() => {
onRejected(this.reason)
})
}
}
}
到这里实现了存在异步时,等待返回最终状态再执行回调,使用下
new Promise((resolve) => {
setTimeout(() => {
resolve('ok')
},2000)
}).then(res => console.log('2秒后', res)) // 等2秒后输出结果
加强 🔨🔨
Promise
支持无限链式调用,每次.then
又返回一个可以.then
的Promise
对象
function resolvePromise(promise2, x, resolve, reject) {
// promise2 === x 会造成循环调用直接抛错
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise'))
}
if ((typeof x === 'object' && x !== null) || typeof x === 'function') {
try {
let then = x.then
if (typeof then === 'function') {
then.call(x, y => {
resolvePromise(promise2, y, resolve, reject)
}, r => {
reject(r)
})
} else {
// 普通对象或普通函数
resolve(x)
}
} catch(e) {
reject(e)
}
} else {
// 普通值直接返回
resolve(x)
}
}
class Promise {
constructor(props) {
// ...
}
then(onFullfilled, onRejected) {
// 当未传入 onFullfilled/onRejected 时,给默认函数
onFullfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
onRejected = typeof onFulfilled === 'function' ? onRejected: err => { throw err }
// 每次执行 .then 返回一个新的 Promise 对象
let promise2 = new Promise((resolve, reject) => {
if (this.status === RESOLVED) {
// 添加定时器是因为当处理当前结果时还取不到 promise2
setTimeout(() => {
// 捕获异步中出现的错误
try {
// 执行用户的成功回调,取到返回结果
let x = onFullfilled(this.value)
// 对返回结果进行统一处理
resolvePromise(promise2, x, resolve, reject)
} catch(e) {
reject(e)
}
}, 0)
}
if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = onRejected(this.reason)
resolvePromise(promise2, x, resolve, reject)
} catch(e) {
reject(e)
}
}, 0)
}
if (this.status === PENDING) {
this.onFullfilledCallbacks.push(() => {
setTimeout(() => {
try {
let x = onFullfilled(this.value)
resolvePromise(promise2, x, resolve, reject)
} catch(e) {
reject(e)
}
}, 0)
})
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onRejected(this.reason)
resolvePromise(promise2, x, resolve, reject)
} catch(e) {
reject(e)
}
}, 0)
})
}
})
return promise2;
}
}
实现了
promise
链式调用then
返回Promise
对象时取到最终数据的处理- 异常捕获处理
至此 Promise
的实现全部完成 🎉,如果有帮助请点赞分享,感谢!
参考
- Promise a+ 规范 promisesaplus.com/