要实现一个promise首先我们要知道以下几点:
1、对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:
- pending: 初始状态,不是成功或失败状态。
- fulfilled: 意味着操作成功完成。
- rejected: 意味着操作失败。
只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态
2、一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对 Promise 对象添加回调函数,也会立即得到这个结果
以上具体可参考菜鸟教程Promise
话不多说先贴上代码:如下(先不考虑调用静态的resolve和reject的话,如Promise.resolve和Promise.reject)
class MyPromise {
constructor(init) {
this.status = "pending"; //promise的状态有:pending、fulfilled、rejected
this.resoleList = []; //定义一个接收resolve的数组
this.rejectList = []; //定义一个接收reject的数组
this.value = ""; //接收值
//提前捕获异常
try {
init(this._resolve.bind(this), this._reject.bind(this));
} catch (error) {
this._reject.call(this, error);
}
}
then(cb) {
cb && this.resoleList.push(cb); //cb有函数的话,先推到resoleList数组里面
if (this.status === "fulfilled") {
this.resoleList.forEach((v) => {
v(this.value);
});
}
return this; //为了可以链式调用,所有要返回它自己
}
catch(cb) {
cb && this.rejectList.push(cb); //cb有函数的话,先推到rejectList数组里面
if (this.status === "rejected") {
this.rejectList.forEach((v) => {
v(this.value);
});
}
return this; //为了可以链式调用,所有要返回它自己
}
_resolve(value) {
if (this.status === "pending") {
this.status = "fulfilled";
this.value = value;
this.then.call(this);
}
}
_reject(value) {
if (this.status === "pending") {
this.status = "rejected";
this.value = value;
this.catch.call(this);
}
}
}
模拟正常调用一下
new MyPromise((res, rej) => {
res(12344);
}).then((res) => {
console.log("ok:" + res);
})
模拟网络延迟返回
new MyPromise((res, rej) => {
setTimeout(() => {
res(12344);
}, 3000);
}).then((res) => {
console.log("ok:" + res);
});
测试捕获异常
new MyPromise((res, rej) => {
res(sss);//传入一个没有定义的sss进去
}).then((res) => {
console.log("ok:" + res);
}).catch((error) => {
console.log("error", error);
});
捕获正常
模拟状态值改变后不再变化
new MyPromise((res, rej) => {
setTimeout(() => {
rej("异常");//先执行状态为rejected
res(12344);//再测试改成fulfilled
}, 3000);
}).then((res) => {
console.log("网络ok:" + res);
}).catch((error) => {
console.log("error", error);
});
ok,只打印catch的内容,没有执行then内容,说明正常
测试连续then链式调用
new MyPromise((res, rej) => {
setTimeout(() => {
res(12344);
}, 3000);
}).then((res) => {
console.log("网络ok:" + res);
}).then((data) => {
console.log("哈哈", data);
}).catch((error) => {
console.log("error", error);
});
也是能正常执行