Promise
存在三个状态:
padding(等待)、fulfilled(完成)、rejected(拒绝)。⚠️注意:
padding可以转为fulfilled或rejected,且不可逆。fulfilled不能与rejected相互转换。
promise构造函数如何实现?
javascript
const PROMISE_TYPE = {
PADDING: 'padding',
FULFILLED: "fulfilled",
REJECTED: "rejected",
}
export class MyPromise {
constructor(exec) {
//初始化状态为padding
this.state = PROMISE_TYPE.PADDING;
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
//设置resolve方法
const resolve = (value) => {
//只有状态为padding,才允许改变状态
if (this.state === PROMISE_TYPE.PADDING) {
this.value = value;
this.state = PROMISE_TYPE.FULFILLED;
this.onFulfilledCallbacks.forEach((fn) => fn());
}
}
//设置reject方法
const reject = (reason) => {
// //只有状态为padding,才允许改变状态
if (this.state === PROMISE_TYPE.PADDING) {
this.reason = reason;
this.state = PROMISE_TYPE.REJECTED;
this.onRejectedCallbacks.forEach((fn) => fn());
}
}
try {
exec(resolve, reject);
} catch (error) {
reject(error)
}
}
//...
}Promise.then方法如何实现?
javascript
export class MyPromise {
constructor(exec) {
//...详情请看promise构造函数如何实现?
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v;
onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err }
let p2 = new MyPromise((resolve, reject) => {
//处理异步回调
if (this.state === PROMISE_TYPE.PADDING) {
//将成功回调压入成功回调栈中
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(p2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0)
})
//将失败回调压入失败回调栈中
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(p2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0)
})
}
// 处理成功回调结果
if (this.state === PROMISE_TYPE.FULFILLED) {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(p2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0)
}
// 处理失败回调结果
if (this.state === PROMISE_TYPE.REJECTED) {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(p2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0)
}
})
}
}resolvePromisejavascriptconst resolvePromise = (promise2, x, resolve, reject) => { if (promise2 === x) { return reject(new TypeError('Chaining cycle detected for promise #<Promise>')) } let called; if ((typeof x === 'object' && x != null) || typeof x === 'function') { try { let then = x.then; 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 { resolve(x); } } catch (error) { if (called) return; called = true; reject(error); } } else { resolve(x); } }