カスタム実現Promise
29417 ワード
Promiseは重要な知識点であり、心に銘記しなければならない.以下はカスタムで実現したPromiseである.
class MyPromise {
// promise 3
// , ,
static PENDING = "pending";
//
static FULFILLED = "fulfilled";
//
static REJECTED = "rejected";
constructor(excutor) {
//
this.status = MyPromise.PENDING;
//
this.callbacks = [];
//
this.value = undefined;
//
try {
// excutor , resolve reject this undefined
// this resolve reject,
excutor(this.resolve.bind(this), this.reject.bind(this));
} catch (error) {
// reject()
this.reject(error);
}
}
//
resolve(value) {
//
if (this.status === MyPromise.PENDING) {
// , ,
this.status = MyPromise.FULFILLED;
this.value = value;
// setTimeout() ,
setTimeout(() => {
this.callbacks.forEach(callback => {
callback.onResolve(value);
})
})
}
}
//
reject(reason) {
//
if (this.status === MyPromise.PENDING) {
// , ,
this.status = MyPromise.REJECTED;
this.value = reason;
// setTimeout() ,
setTimeout(() => {
this.callbacks.forEach(callback => {
callback.onRejected(value);
})
})
}
}
then(onResolve, onRejected) {
// , ,
//then
// let p = new Promise((resolve,reject)=>{
// resolve(" ")
// })
// p.then().then(value=>console.log(value)) //=>
if (typeof onResolve !== "function") {
onResolve = () => this.value;
}
if (typeof onRejected !== "function") {
onRejected = () => this.value;
}
// MyPromise
let promise = new MyPromise((resolve, reject) => {
//
if (this.status === MyPromise.FULFILLED) {
this.parse(promise, onResolve(this.value), resolve, reject);
}
if (this.status === MyPromise.REJECTED) {
this.parse(promise, onRejected(this.value), resolve, reject);
}
// resolve() setTimeout()
// let p = new Promise((resolve, reject) => {
// setTimeout(() => {
// resolve(" ")
// }, 100);
// })
// p.then(value => console.log(value)) //=>
//
if (this.status === MyPromise.PENDING) {
this.callbacks.push({
onResolve: value => {
this.parse(promise, onResolve(value), resolve, reject);
},
onRejected: value => {
this.parse(promise, onRejected(value), resolve, reject);
}
})
}
})
return promise;
}
parse(promise, result, resolve, reject) {
setTimeout(() => {
// ,
if (promise === result) {
throw new TypeError("Chaining cycle detected");
}
try {
// return , then
// return MyPromise return
if (result instanceof MyPromise) {
// resolve(), reject()
// result.then(
// value => {
// resolve(value);
// },
// reason => {
// reject(reason);
// }
// )
//
result.then(resolve, reject);
} else {
resolve(this.value);
}
} catch (error) {
// then
reject(error);
}
})
}
static resolve(value) {
return new MyPromise((resolve, reject) => {
if (value instanceof MyPromise) {
value.then(resolve, reject);
} else {
resolve(value);
}
})
}
static reject(value) {
return new MyPromise((resolve, reject) => {
// MyPromise ,
if (value instanceof MyPromise) {
value.then(resolve, reject);
} else {
reject(value);
}
})
}
// promise
static all(promises) {
const values = [];
return new MyPromise((resolve, reject) => {
promises.forEach(promise => {
promise.then(
value => {
values.push(value);
//
if (values.length === promises.length) {
resolve(values);
}
},
reason => {
//
reject(reason);
}
)
})
});
}
// promise promise
static race(promises) {
return new MyPromise((resolve, reject) => {
promises.forEach(promise => {
promise.then(
value => {
//
resolve(value);
},
reason => {
//
reject(reason);
}
)
})
});
}
}