尝试 Promise A+
作者:Jeannette
- 2021 年 11 月 25 日
本文字数:3074 字
阅读完需:约 10 分钟
Promise 中有 3 种状态 Pending、Fulfilled、Rejected
状态的转变是:
Pending To onFulfilled To fulfilled
Pending To Rejected To rejected
const PENDING ='pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MPromise {
FULFILLED_CALLBACK_LIST = [];
REJECTED_CALLBACK_LIST = [];
_status = PENDING;
constructor(fn) {
this.status = PENDING;
this.value = null;
this.reason = null;
try {
fn(this.resolve.bind(this), this.reject.bind(this))
} catch (err) {
console.log('err: ', err);
this.reject(err);
}
}
get status() {
return this._status;
}
set status(newStatus) {
this._status = newStatus;
switch (newStatus) {
case FULFILLED:
this.FULFILLED_CALLBACK_LIST.forEach(callback => {
console.log('callback: ', callback);
callback(this.value);
})
break;
case REJECTED:
this.REJECTED_CALLBACK_LIST.forEach(callback => {
callback(this.reason);
})
break;
default:
break;
}
}
resolve(value) {
if (this.status === PENDING) {
this.value = value;
this.status = FULFILLED;
}
}
reject(reason) {
if (this.status === REJECTED) {
this.reason = reason
this.status = REJECTED;
}
}
then(onFulfilled, onRejected) {
console.log('onFulfilled: ', onFulfilled);
console.log('status', this.status);
const fulfilledFn = this.isFunction(onFulfilled) ? onFulfilled : (value) => value;
const rejectedFn = this.isFunction(onRejected) ? onFulfilled : (reason) => { throw reason };
const fulFilledFnWithCatch = (resolve, reject, newPromise) => {
queueMicrotask(() => {
try {
if (!this.isFunction(onFulfilled)) {
resolve(this.value)
} else {
const x = fulfilledFn(this.value)
this.resolvePromise(newPromise, x, resolve, reject);
}
} catch (e) {
reject(e)
}
})
}
const rejectedFnWithCatch = (resolve, reject, newPromise) => {
queueMicrotask(() => {
try {
if (!this.isFunction(onRejected)) {
reject(this.reason)
} else {
const x = rejectedFn(this.reason);
this.resolvePromise(newPromise, x, resolve, reject);
}
} catch (e) {
reject(e)
}
})
}
if (this.status === FULFILLED) {
let newPromise = new MPromise((resolve, reject) => {
return fulFilledFnWithCatch(resolve, reject, newPromise)
})
return newPromise;
} else if (this.status === REJECTED) {
let newPromise = new MPromise((resolve, reject) => rejectedFnWithCatch(resolve, reject, newPromise))
return newPromise
} else if (this.status === PENDING){
let newPromise = new MPromise((resolve, reject) => {
this.FULFILLED_CALLBACK_LIST.push(() => fulFilledFnWithCatch(resolve, reject, newPromise));
this.REJECTED_CALLBACK_LIST.push(() => rejectedFnWithCatch(resolve, reject, newPromise));
})
return newPromise
}
}
/**
* 对于Promise的状态一个统一的处理, 直到不是object,function, promise才直接resolve出去,或者遇到报错reject出去
* @param {}} newPromise
* @param {*} x
* @param {*} resolve
* @param {*} reject
*/
resolvePromise(newPromise, x, resolve, reject) {
console.log('newPromise, x, resolve, reject: ', newPromise, x, resolve, reject);
// let obj = resolve(111) === then(() => 111)
if (newPromise === x) {
return reject(new TypeError('xxxxxxxxxxxxxxx'))
}
if (x instanceof MPromise) {
x.then((y) => {
this.resolvePromise(newPromise, y, resolve, reject)
}, reject)
} else if (typeof x === 'object' || this.isFunction(x)) {
if (x === null) {
return resolve(x);
}
let then = null;
try {
then = x.then;
} catch(error) {
return reject(error)
}
if (this.isFunction(then)) {
console.log('then: ', then);
let called = false;
try {
then.call(x, (y) => {
if (called) {
return;
}
called = true;
this.resolvePromise(newPromise, y, resolve, reject)
}, () => {
if (called) {
return
}
called = true;
reject(r)
})
} catch(error) {
if (called) {
return;
}
reject(error);
}
} else {
resolve(x);
}
} else {
resolve(x);
}
}
catch(onRejected) {
return this.then(null, onRejected);
}
isFunction(params) {
return typeof params === 'function';
}
}
const promise1 = new MPromise((resolve, reject) => {
resolve({
x: 100,
then() {
console.log(this.x)
}
});
})
const promise2 = promise1.then((res) => {
console.log('res: ', res);
return
})
promise2.then(res => {
console.log('res2: ', res);
})
console.log('promise2', promise2);
复制代码
划线
评论
复制
发布于: 1 小时前阅读数: 4
Jeannette
关注
还未添加个人签名 2019.07.19 加入
科学技术是第一生产力
评论