自己实现一个promise
2020-08-21 本文已影响0人
若年
整理自后盾人网站
class MyPromise {
static PENDING = "pending";
static FULFILLED = "fulfilled";
static REJECTED = "rejected";
constructor(executor) {
this.status = MyPromise.PENDING;
this.value = null;
this.callbacks = [];
try {
executor(this.resolve.bind(this), this.reject.bind(this));
} catch (error) {
this.reject(error);
}
}
resolve(value) {
if (this.status == MyPromise.PENDING) {
this.status = MyPromise.FULFILLED;
this.value = value;
setTimeout(()=>{
this.callbacks.map(callback => {
callback.onFulfilled(value);
});
})
}
}
reject(value) {
if (this.status == MyPromise.PENDING) {
this.status = MyPromise.REJECTED;
this.value = value;
setTimeout(()=>{
this.callbacks.map(callback => {
callback.onRejected(value);
});
})
}
}
then(onFulfilled,onRejected){
if (typeof onFulfilled != "function") {
onFulfilled = value =>value;;
}
if (typeof onRejected != "function") {
onRejected = value => value;
}
return new MyPromise((resolve,reject)=>{
if(this.status ==MyPromise.PENDING){
this.callbacks.push({
onFulfilled:value=>{
this.parse(promise,onFulfilled(this.value), resolve, reject);
},
onRejected: value => {
this.parse(promise,onRejected(this.value), resolve, reject);
}
})
}
if (this.status == MyPromise.FULFILLED) {
setTimeout(() => {
this.parse(promise,onFulfilled(this.value), resolve, reject);
});
}
if (this.status == MyPromise.REJECTED) {
setTimeout(() => {
this.parse(promise,onRejected(this.value), resolve, reject);
});
}
});
}
parse(promise,result, resolve, reject) {
if(promise ==result){
throw new TypeError("Chaining cycle detected for promise");
}
try {
if (result instanceof MyPromise) {
result.then(resolve, reject);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
}
static resolve(value) {
return new MyPromise((resolve, reject) => {
if (value instanceof MyPromise) {
value.then(resolve, reject);
} else {
resolve(value);
}
});
}
static reject(reason) {
return new MyPromise((_, reject) => {
reject(reason);
});
}
static all(promises) {
let resolves = [];
return new MyPromise((resolve, reject) => {
promises.forEach((promise, index) => {
promise.then(
value => {
resolves.push(value);
if (resolves.length == promises.length) {
resolve(resolves);
}
},
reason => {
reject(reason);
}
);
});
});
}
static race(promises) {
return new MyPromise((resolve, reject) => {
promises.map(promise => {
promise.then(value => {
resolve(value);
});
});
});
}
}
使用测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="myPromise.js"></script>
<script>
//使用测试
let p1 = new MyPromise((resolve, reject) => {
resolve("测试");
}).then(value => {
console.log(value);
},
reason => {
console.log(reason);
}).then(
value => {
console.log(value);
},
reason => {
console.log(reason);
}
);
let p2 = new MyPromise((resolve, reject) => {
resolve("测试2");
}).then(value => {
console.log(value);
},
reason => {
console.log(reason);
}).then(
value => {
console.log(value);
},
reason => {
console.log(reason);
}
);;
MyPromise.resolve("完成").then(value => {
console.log(value);
});
MyPromise.all([p1,p2]).then((value)=>{
console.log(value);
})
</script>
</body>
</html>