class MyPromise {
constructor(fn) {
this.state = "pending";
this.result = null;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
try {
fn(this.resolve, this.reject);
} catch (err) {
throw Error(err);
}
}
resolve(value) {
if (this.state !== "pending") {
return;
}
this.state = "fulfilled";
this.result = value;
while (this.onFulfilledCallbacks.length) {
this.onFulfilledCallbacks.shift()();
}
}
reject(value) {
if (this.state !== "pending") {
return;
}
this.state = "rejected";
this.result = value;
while (this.onRejectedCallbacks.length) {
this.onRejectedCallbacks.shift()();
}
}
then(onFulfilled, onRejected) {
onFulfilled =
typeof onFulfilled === "function" ? onFulfilled : (val) => val;
onRejected =
typeof onRejected === "function"
? onRejected
: (reason) => {
throw Error(reason);
};
var thenPromise = new MyPromise((resolve, reject) => {
const handlePromise = (cb) => {
setTimeout(() => {
try {
const result = cb(this.result);
if (result === thenPromise) {
throw Error("不能是自己");
}
if (result instanceof MyPromise) {
result.then(resolve, reject);
} else {
resolve(resolve);
}
} catch (err) {
reject(err);
throw Error(err);
}
});
};
if (this.state === "fulfilled") {
handlePromise(onFulfilled);
} else if (this.state === "rejected") {
handlePromise(onRejected);
} else {
this.onFulfilledCallbacks.push(handlePromise(onFulfilled));
this.onRejectedCallbacks.push(handlePromise(onRejected));
}
});
return thenPromise;
}
}
原型上的方法
const all = (promiseList) => {
const result = [];
let count = 0;
return new Promise((resolve, reject) => {
const addData = (res, index) => {
result[index] = res;
count++;
if (count === promiseList.length) {
resolve(result);
}
};
promiseList.forEach((p, index) => {
if (p instanceof Promise) {
p.then((res) => {
addData(res, index);
}).catch((err) => {
reject(err);
});
} else {
addData(p, index);
}
});
});
};
const race = (promiseList) => {
return new Promise((resolve, reject) => {
promiseList.forEach((p) => {
if (p instanceof Promise) {
p.then((resp) => {
resolve(resp);
}).catch((err) => {
reject(err);
});
} else {
resolve(p);
}
});
});
};
const any = (promiseList) => {
let count = 0;
return new Promise((resolve, reject) => {
promiseList.forEach((p) => {
if (p instanceof Promise) {
p.then((resp) => {
resolve(resp);
}).catch((err) => {
count++;
if (count === promiseList.length) {
reject(err);
}
});
} else {
resolve(resp);
}
});
});
};
const allsettled = (promiseList) => {
const result = [];
let count = 0;
return new Promise((resolve, reject) => {
const addData = (value, status, i) => {
result[i] = {
status,
value,
};
count++;
if (count === promiseList.length) {
resolve(result);
}
};
promiseList.forEach((p, index) => {
if (p instanceof Promise) {
p.then((resp) => {
addData(resp, "fulfilled", index);
}).catch((err) => {
addData(resp, "rejected", index);
});
} else {
addData(p, "fulfilled", index);
}
});
});
};