function Promise(executor) {
this.status = "pending";
this.value = null;
this.reason = null;
this.onfulfilledArray = [];
this.onrejectedArray = [];
let resolve = (value) => {
if (value instanceof Promise) {
return value.then(resolve, reject);
}
setTimeout(() => {
if (this.status === "pending") {
this.value = value;
this.status = "fulfilled";
this.onfulfilledArray.forEach((func) => {
func(value);
});
}
});
};
let reject = (reason) => {
setTimeout(() => {
if (this.status === "pending") {
this.reason = reason;
this.status = "rejected";
this.onrejectedArray.forEach((func) => {
func(reason);
});
}
});
};
try {
executor(resolve, reject);
} catch (error) {
reject(e);
}
}
const resolvePromise = (promise2, result, resolve, reject) => {
if (result === promise2) {
reject(new TypeError("error due to circular reference"));
}
let consumed = false;
let thenable;
if (result instanceof Promise) {
if (result.status === "pending") {
result.then(function (data) {
resolvePromise(promise2, data, resolve, reject);
}, reject);
} else {
result.then(resolve, reject);
}
return;
}
let isComplexResult = (target) =>
(typeof target === "function" || typeof target === "object") &&
target !== null;
if (isComplexResult(result)) {
try {
thenable = result.then;
if (typeof thenable === "function") {
thenable.call(
result,
function (data) {
if (consumed) {
return;
}
consumed = true;
return resolvePromise(promise2, data, resolve, reject);
},
function (error) {
if (consumed) {
return;
}
consumed = true;
return reject(error);
}
);
} else {
resolve(result);
}
} catch (error) {
if (consumed) {
return;
}
consumed = true;
return reject(e);
}
} else {
resolve(result);
}
};
Promise.prototype.then = function (onfulfilled, onrejected) {
let promise2;
if (this.status === "fulfilled") {
return (promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
try {
let result = onfulfilled(this.value);
resolvePromise(promise2, result, resolve, reject);
} catch (error) {
reject(error);
}
});
}));
}
if (this.status === "rejected") {
return (promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
try {
let result = onrejected(this.value);
resolvePromise(promise2, result, resolve, reject);
} catch (error) {
reject(error);
}
});
}));
}
if (this.status === "pending") {
return (promise2 = new Promise((resolve, reject) => {
this.onfulfilledArray.push(() => {
try {
let result = onfulfilled(this.value);
resolvePromise(promise2, result, resolve, reject);
} catch (error) {
reject(error);
}
});
this.onrejectedArray.push(() => {
try {
let result = onrejected(this.reason);
resolvePromise(promise2, result, resolve, reject);
} catch (error) {
reject(error);
}
});
}));
}
};
Promise.prototype.catch = function (catchFunc) {
return this.then(null, catchFunc);
};
Promise.resolve = function (value) {
return new Promise((resolve, reject) => {
resolve(value);
});
};
Promise.reject = function (value) {
return new Promise((resolve, reject) => {
reject(value);
});
};
Promise.all = function (promiseArray) {
if (!Array.isArray(promiseArray)) {
throw new TypeError("The arguments should be an array!");
}
return new Promise((resolve, reject) => {
try {
let resultArray = [];
const length = promiseArray.length;
for (let i = 0, item; (item = promiseArray[i++]);) {
item.then((data) => {
resultArray.push(data);
if (resultArray.length === length) {
resolve(resultArray);
}
}, reject);
}
} catch (error) {
reject(error);
}
});
};
Promise.race = function (promiseArray) {
if (!Array.isArray(promiseArray)) {
throw new TypeError("The arguments should be an array!");
}
return new Promise((resolve, reject) => {
try {
for (let i = 0, item; (item = promiseArray[i++]);) {
item.then(resolve, reject);
}
} catch (error) {
reject(error);
}
});
};
let cs = new Promise((res, err) => {
setTimeout(() => {
res("da");
}, 2000);
});
let cs2 = new Promise((res, err) => {
setTimeout(() => {
res("da2");
}, 5000);
});
Promise.all([cs, cs2]).then((data) => {
console.log(data);
});