/**
* @params:setup fn
* 属性:
* 静态方法:resolve(),reject(),all(),race(),
* 原型方法:then(),catch(),finaly(),
*/
class MyPromise {
// 状态
static PENDING = "pending";
static FULFILLED = "fulfilled";
static REJECTED = "rejected";
constructor(executor) {
const { PENDING, FULFILLED, REJECTED } = MyPromise;
this._state = PENDING;
this._value = null; // 值或者报错
this._resolveCallbacks = [];
this._rejectCallbacks = [];
try {
executor(this._resolve.bind(this), this._reject.bind(this));
} catch (e) {
this._reject(e);
}
}
// 静态方法
static resolve(val) {
// 1.promise return promise;
/* 2.thenable
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
}
*/
// 3.其他类型
if (val instanceof Promise || val instanceof MyPromise) {
return val;
}
if (val && typeof val.then === "function") {
return new MyPromise(function (resolve, reject) {
try {
val.then(resolve, reject);
} catch (e) {
reject(e);
}
});
}
return new MyPromise(function (resolve, reject) {
resolve(val);
});
}
static reject(val) {
return new MyPromise((resolve, reject) => {
reject(val);
});
}
static all(promiseArr) {
let count = 0,
result = [];
return new MyPromise(function (resolve, reject) {
promiseArr.forEach((promise, index) => {
MyPromise.resolve(promise).then(
(res) => {
result[index] = res;
if (++count == promiseArr.length) {
resolve(result);
count = 0;
}
},
(err) => {
reject(err);
}
);
});
});
}
static race(promiseArr) {
return new MyPromise(function (resolve, reject) {
promiseArr.forEach((promise) => {
MyPromise.resolve(promise).then(
(res) => {
resolve(res);
},
(err) => {
reject(err);
}
);
});
});
}
// 原型方法
then(onFulfilled, onRejected) {
onFulfilled =
typeof onFulfilled == "function" ? onFulfilled : function () {};
onRejected =
typeof onRejected == "function" ? onRejected : function () {};
const { PENDING, FULFILLED, REJECTED } = MyPromise;
const p = new MyPromise((resolveNext, rejectNext) => {
const _fulfiledFn = (value) => {
try {
const result = onFulfilled(value);
// 1.promise return promise;
/* 2.thenable
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
}
*/
// 3.其他类型
if (
result instanceof Promise ||
result instanceof MyPromise
) {
result.then(resolveNext, rejectNext);
} else if (
result &&
typeof result.then === "function"
) {
result.then(resolveNext, rejectNext);
} else {
resolveNext(result);
}
} catch (err) {
rejectNext(err);
}
};
const _rejectedFn = (reason) => {
try {
const result = onRejected(reason);
// 1.promise return promise;
/* 2.thenable
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
}
*/
// 3.其他类型
if (
result instanceof Promise ||
result instanceof MyPromise
) {
result.then(resolveNext, rejectNext);
} else if (
result &&
typeof result.then === "function"
) {
result.then(resolveNext, rejectNext);
} else {
resolveNext(result);
}
} catch (err) {
rejectNext(err);
}
};
switch (this._state) {
case PENDING:
// 保存回调函数
this._resolveCallbacks.push(_fulfiledFn);
this._rejectCallbacks.push(_rejectedFn);
break;
case FULFILLED:
_fulfiledFn(this._value);
break;
case REJECTED:
_rejectedFn(this._value);
break;
}
});
return p;
}
catch(onRejected) {
return this.then(null, onRejected);
}
finaly(callback) {
this.then(
(value) => MyPromise.resolve(callback()).then(() => value),
(err) =>
MyPromise.resolve(callback()).then(() => {
throw err;
})
);
}
// 回调
_resolve(value) {
const { PENDING, FULFILLED, REJECTED } = MyPromise;
// 1.改变状态
if (this._state !== PENDING) return;
const _runFulfilledCbs = (val) => {
this._resolveCallbacks.forEach((onFulfilled) => {
onFulfilled(val);
});
this._resolveCallbacks.length = 0;
};
const _runRejectedCbs = (reason) => {
this._rejectCallbacks.forEach((onRejected) => {
onRejected(reason);
});
this._rejectCallbacks.length = 0;
};
if (value instanceof MyPromise) {
// value是promise,当前promise的状态取决于value
value.then(
(val) => {
this._state = FULFILLED;
this._value = val;
_runFulfilledCbs(val);
},
(reason) => {
this._state = REJECTED;
this._value = reason;
_runRejectedCbs(reason);
}
);
return;
}
// 调用成功回调
setTimeout(() => {
// 状态的改变也应该放到下个周期,否则会在当前周期调用then函数的回调
this._state = FULFILLED;
this._value = value;
_runFulfilledCbs(value);
}, 0);
}
_reject(reason) {
const { PENDING, FULFILLED, REJECTED } = MyPromise;
if (this.state !== PENDING) {
return;
}
// 调用拒绝回调
const _runRejectedCbs = (reason) => {
this._rejectCallbacks.forEach((onRejected) => {
onRejected(reason);
});
this._rejectCallbacks.length = 0;
};
setTimeout(() => {
this._state = REJECTED;
this._value = reason;
_runRejectedCbs(reason);
}, 0);
}
}
// 测试代码
// var promise = new MyPromise((resolve, reject) => {
// console.log("step-");
// setTimeout(() => {
// resolve(123);
// }, 1000);
// });
// promise.then((value) => {
// console.log("step--");
// console.log("value", value);
// });
// console.log("end");
let thenable = {
then: function (resolve, reject) {
resolve(42);
},
};
const p2 = MyPromise.resolve(thenable);
p2.then((val) => {
console.log(val);
});