promise A+ 规范
- Promise 有三种状态:pending(进行中)、fulfilled(成功)、rejected(失败)。有一个执行器executor(new Promise 时传入的函数),且立即执行
- 状态转换:
默认状态为pending
状态只能 pending => fulfilled
pending=> rejected
两个转换状态方法
成功:resolve(),状态pending => fulfilled,内部维护成功值 value undefined | thenable | promise
失败:reject()状态pending=> rejected,内部维护失败原因 reason - then方法:接收两个回调函数onFulfilled,onRejected
成功时:执行onFulfilled,参数成功值value
失败时:执行onRejected,参数为失败原因reason
有异常:执行onRejeted - Promise 可以连式调用,即then 返回的为新的promise
- 一个Promise可以重复调用
- then 返回值可穿透
- then 为异步执行
Promise 简单实现
const PENDING = 'PENDING';
const FULFILLED = 'FULFILLED';
const REJECTED = 'REJECTED';
class Promise {
constructor(executor) {
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
this.onResolvedCallbacks = [];
this.onRejectedCallbacks = [];
let resolve = value => {
if(this.status === PENDING) {
this.status = FULFILLED;
this.value = value;
this.onResolvedCallbacks.forEach(fn => fn());
}
}
let reject = reason => {
if(this.status === PENDING) {
this.status = REJECTED;
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn());
}
}
try {
executor(resolve, reject);
} catch(error) {
reject(error);
}
}
if (this.status === FULFILLED) {
onFulfilled(this.value);
}
if (this.status === REJECTED) {
onRejected(this.reason);
}
if (this.status === PENDING) {
this.onResolvedCallbacks.push(() => {
onFulfilled(this.value);
})
this.onRejectedCallbacks.push(() => {
onRejected(this.reason);
})
}
}
class myPromise {
constructor(executor) {
this.status = 'PENDING';
this.value = undefined;
this.reason = undefined;
this.onResolvedCallbacks = [];
this.onRejectedCallbacks = [];
let resolve = value => {
if (this.status === 'PENDING') {
this.status = 'FULFILLED';
this.value = value;
this.onResolvedCallbacks.forEach(fn => fn());
}
}
let reject = reason => {
if (this.status === 'PENDING') {
this.status = 'REJECTED';
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn());
}
}
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : error => { throw error };
let promise2 = new myPromise((resolve, reject) => {
if (this.status === 'FULFILLED') {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
}
if (this.status === 'REJECTED') {
setTimeout(() => {
try {
let x = onRejected(this.reason);
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
}
if (this.status === 'PENDING') {
this.onResolvedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onRejected(this.reason);
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
}
});
return promise2;
} catch(onRejected) {
return this.then(null, onRejected);
}
resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Promise 不能循环连式调用自身'));
}
let called = false;
if (x instanceof Promise) {
x.then(y => {
this.resolvePromise(promise2, y, resolve, reject);
}, error => {
reject(error);
});
} else if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
try {
let then = x.then;
if (typeof then === 'function') {
then.call(x, y => {
if (called) return;
called = true;
this.resolvePromise(promise2, y, resolve, reject);
}, error => {
if (called) return;
called = true;
reject(error);
});
} else {
resolve(x);
}
} catch (error) {
if (called) return;
called = true;
reject(error);
}
} else {
resolve(x);
}
}