/**
* promise 的 三种状态
*/
const PENDING = "PENDING",
FULFILLED = "FULFILLED",
REJECED = "REJECTED";
/**
*
* @param {*} p2 p2 就是promise
* @param {*} x onFulfilled 或者 onRejected的返回值
* @param {*} resolve
* @param {*} reject
* @returns
*/
function resolvePromise(p2, x, resolve, reject) {
// console.log(p2===x);
if (p2 === x) {
// 解决循环引用
return reject(new TypeError(" Chaining cycle detected for promise #<MyPromiseFinal>"))
}
// called 是否已经调用过resolve 或者是reject
let called = false;
// 2.3.3
if ((typeof x === "object" && x !== null) || typeof x === "function") {
try {
// 获取then的时候可能被劫持 Object.defineProperty 中被劫持
let then = x.then;
if (typeof then === "function") {
// Promise 可以断定
then.call(x, (y) => {
if (called) return;
called = true;
// y可能是 MyPromise对象
resolvePromise(p2, y, resolve, reject);
// resolve(y);
}, (r) => {
if (called) return;
called = true;
reject(r);
})
} else {
resolve(x);
}
} catch (error) {
if (called) return;
called = true;
reject(error);
}
} else {
resolve(x);
}
}
/**
*
* @param {*} x 判断x是否是promise
* @returns
*/
function isPromise(x){
if((typeof x === "object" && x !== null) || typeof x === "function"){
try {
let then = x.then;
if(typeof then === "function"){
return true;
}else{
return false;
}
} catch (error) {
return false;
}
}
return false;
}
/**
*
* @param {data} data
* @returns 判断数据是否是可迭代对象
*/
function isIterable(data){
return data !== null && data !== undefined && typeof data[Symbol.iterator] === 'function'
}
class MyPromiseFinal {
constructor(fn) {
// 初始化状态
this.status = PENDING;
// 成功值
this.value = undefined;
// 失败的元婴赋值为
this.reason = undefined;
// 成功态的回调函数集合
this.onFulFilledCallbacks = [];
// 失败态的回调函数集合
this.onRejectedCallbacks = [];
// 将promise 从 pending -> resolve的状态
let resolve = (value) => {
// 判断是否是thenable对象
if(value instanceof MyPromiseFinal){
// 如果value 还是 MyPromiseFinal的实例 那么久执行then
// 如果还是MyPromiseFinal 那么继续走resolve 直到不是promise为止
return value.then(resolve,reject);
}
if (this.status === PENDING) {
this.status = FULFILLED;
this.value = value;
// 发布
this.onFulFilledCallbacks.forEach(fn => fn());
}
}
// 将promise 从 pending -> rejected的状态 赋值原因
let reject = (reason) => {
if (this.status === PENDING) {
this.status = REJECED;
this.reason = reason;
// 发布
this.onRejectedCallbacks.forEach(fn => fn());
}
}
// executor
fn(resolve, reject);
}
// x 可能是 1 字符串1 bool 类型 但是可能是 Promise
then(onFulFilled, onRejected) {
// then 穿透 onFulfilled onRejected 是可选参数
onFulFilled = typeof onFulFilled === "function" ? onFulFilled : value => value; //直接返回成功态的值
onRejected = typeof onRejected === "function" ? onRejected : reason => { throw (reason) };
// then 必须返回一个promise对象
let promise2 = new MyPromiseFinal((resolve, reject) => {
if (this.status === FULFILLED) {
// 为什么使用 setTimeout 参考promiseA+ 3.1
setTimeout(() => {
// if (called) return;
// called = true;
try {
let x = onFulFilled(this.value);// 可能onFulFilled 抛出错误
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error)
}
}, 0);
}
if (this.status === REJECED) {
setTimeout(() => {
// if (called) return;
// called = true;
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error)
}
}, 0);
}
if (this.status === PENDING) {
this.onFulFilledCallbacks.push(() => {
setTimeout(() => {
try {
let x = onFulFilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error)
}
}, 0);
})
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error)
}
}, 0);
})
}
});
return promise2
}
catch(reject) {
return this.then(null, reject)
}
/**
* Promise.reoslve("common value").finally(()=>{
* console.log(1);
* return new Promise((resolve,reject)=>{
* reject(123);
* })
* }).then(data=>{
* console.log(data);
* }).catch(err=>console.log(err))
*/
finally(finallyCallback){
return this.then((value)=>{
return MyPromiseFinal.resolve(finallyCallback()).then(()=>{
return value
})
},(reason)=>{
return MyPromiseFinal.resolve(finallyCallback()).then(()=>{
throw reason
})
})
}
static resolve(value){
return new MyPromiseFinal((resolve,reject)=>{
resolve(value);
})
}
static reject(reason){
return new MyPromiseFinal((resolve,reject)=>{
reject(reason);
})
}
static all(promiseArr){
let id = 0,
resArr =[];
function formatPromise(value,idx,resolve){
resArr[idx] = value;
if(++id === promiseArr.length){
resolve(resArr);
}
}
return new MyPromiseFinal((resolve,reject)=>{
promiseArr.forEach((promise,idx)=>{
if(isPromise(promise)){
promise.then((value)=>{
formatPromise(value,idx,resolve);
},reject)
}else{
formatPromise(promise,idx,resolve);
}
})
})
}
static race(promiseArr){
let res;
function formatRacePromise (x,resolve,reject){
if(res)return;
res = x;
if(resolve){
resolve(x);
}else{
reject(x);
}
}
return new MyPromiseFinal((resolve,reject)=>{
promiseArr.map((promise,idx)=>{
if(isPromise(promise)){
promise.then((res)=>{
formatRacePromise(res,resolve,reject);
},(reason) =>{
formatRacePromise(reason,null,reject);
// reject(reason)
})
}else{
resolve(promise);
}
})
})
}
static race2(promiseArr){
return new MyPromiseFinal((resolve,reject)=>{
promiseArr.map((promise,idx) => {
if(isPromise(promise)){
promise.then(resolve,reject);
}
})
})
}
static allSettled(promiseArr){
let resArr = [],
idx = 0;
function handlePromiseRes(status,value,resolve){
switch(status){
case "fulfilled":
resArr.push({
status,
value
});
break;
case "rejected":
resArr.push({
status,
reason:value
})
}
if(++idx === promiseArr.length){
resolve(resArr);
}
}
return new MyPromiseFinal((resolve,reject)=>{
if(!isIterable(promiseArr)){
throw new TypeError(promiseArr +" is not iterable (cannot read property Symbol(Symbol.iterator))")
}
if(promiseArr.length===0){
resolve(resArr);
}
promiseArr.map((promise,idx)=>{
if(isPromise(promise)){
promise.then((value)=>{
handlePromiseRes("fulfilled",value, resolve);
},(reason) =>{
handlePromiseRes("rejected",reason, resolve);
})
}else{
handlePromiseRes("fulfilled",promise, resolve);
}
})
})
}
}
// 检测Promise 是否符合promiseA+规范
MyPromiseFinal.defer = MyPromiseFinal.deferred = function () {
let deferred = {};
deferred.promise = new MyPromiseFinal((resolve, reject) => {
deferred.resolve = resolve;
deferred.reject = reject;
})
return deferred;
}
module.exports = MyPromiseFinal;
// 循环 引用的例子
/* let cycleP = new Promise((resolve,reject)=>{
resolve("123")
})
let cycleP2 = cycleP.then(data=>{
return cycleP2
}) */