https://www.bilibili.com/video/BV1Lb411f766?p=14&vd_source=0910f4debbd07e1a7671bae76639d8fe
// 1. 手写Promise - 结构的设计
const PROMISE_STATUS_PENDING = 'pending';
const PROMISE_STATUS_FULFILLED = 'fulfilled';
const PROMISE_STATUS_REJECTED = 'rejected';
class MyPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING;
const resolve = value => {
if (this.status === PROMISE_STATUS_PENDING) {
this.status = PROMISE_STATUS_FULFILLED;
console.log('resolve');
}
}
const reject = reason => {
if (this.status === PROMISE_STATUS_PENDING) {
this.status = PROMISE_STATUS_REJECTED;
console.log('reject');
}
}
executor(resolve, reject);
}
}
const p = new MyPromise((resolve, reject) => {
resolve();
reject();
})
// 2. 手写Promise - then方法设计
const PROMISE_STATUS_PENDING = 'pending';
const PROMISE_STATUS_FULFILLED = 'fulfilled';
const PROMISE_STATUS_REJECTED = 'rejected';
class MyPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING;
this.value = undefined;
this.reason = undefined;
const resolve = value => {
if (this.status === PROMISE_STATUS_PENDING) {
this.status = PROMISE_STATUS_FULFILLED;
queueMicrotask(() => {
this.value = value;
this.onFulfilled(this.value)
})
console.log('resolve');
}
}
const reject = reason => {
if (this.status === PROMISE_STATUS_PENDING) {
this.status = PROMISE_STATUS_REJECTED;
queueMicrotask(() => {
this.reason = reason;
this.onRejected(this.reason)
})
console.log('reject');
}
}
executor(resolve, reject);
}
then(onFulfilled, onRejected) {
this.onFulfilled = onFulfilled;
this.onRejected = onRejected;
}
}
const p = new MyPromise((resolve, reject) => {
resolve(111);
reject(222);
})
p.then(res => {
console.log(res, 'res1');
}, err => {
console.log(err, 'err1');
})
// 3. 手写Promise - then方法优化(支持调用多次then,定时器内使用then方法)
const PROMISE_STATUS_PENDING = 'pending';
const PROMISE_STATUS_FULFILLED = 'fulfilled';
const PROMISE_STATUS_REJECTED = 'rejected';
class MyPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING;
this.value = undefined;
this.reason = undefined;
this.onFulfilledFns = [];
this.onRejectedFns = [];
const resolve = (value) => {
if (this.status === PROMISE_STATUS_PENDING) {
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return; // 阻止成功和失败一起调用
this.status = PROMISE_STATUS_FULFILLED;
this.value = value;
this.onFulfilledFns.forEach(fn => fn(this.value))
})
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_PENDING) {
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return; // 阻止成功和失败一起调用
this.status = PROMISE_STATUS_REJECTED;
this.reason = reason;
this.onRejectedFns.forEach(fn => fn(this.reason))
})
}
}
executor(resolve, reject)
}
then(onFulfilled, onRejected) {
if (this.status === PROMISE_STATUS_FULFILLED && onFulfilled) {
onFulfilled(this.value)
} else if (this.status === PROMISE_STATUS_REJECTED && onRejected) {
onRejected(this.reason)
} else if (this.status === PROMISE_STATUS_PENDING) {
this.onFulfilledFns.push(onFulfilled)
this.onRejectedFns.push(onRejected)
}
}
}
const p = new MyPromise((resolve, reject) => {
resolve(111);
reject(222);
})
p.then((res) => {
console.log(res, 'res1');
}, (err) => {
console.log(err, 'err1');
})
p.then((res) => {
console.log(res, 'res2');
}, (err) => {
console.log(err, 'err2');
})
setTimeout(() => {
p.then((res) => {
console.log(res, 'res3');
}, (err) => {
console.log(err, 'err3');
})
}, 1000);
// 4. 手写Promise - then链式调用
const PROMISE_STATUS_PENDING = 'pending';
const PROMISE_STATUS_FULFILLED = 'fulfilled';
const PROMISE_STATUS_REJECTED = 'rejected';
class MyPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING;
this.value = undefined;
this.reason = undefined;
this.onFulfilledFns = [];
this.onRejectedFns = [];
const resolve = (value) => {
if (this.status === PROMISE_STATUS_PENDING) {
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return;
this.status = PROMISE_STATUS_FULFILLED;
this.value = value;
this.onFulfilledFns.forEach(fn => fn(this.value))
})
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_PENDING) {
queueMicr