class MyPromise {
constructor(func) {
this.task = [];
this.errTask=undefined;
this.ball = null;
this.status=undefined;
setTimeout(() => {
func(this.resolve.bind(this), this.reject.bind(this))
}, 0)
}
resolve(obj) {
if(this.status) return;
this.status="resolved";
this.ball = obj;
console.log(this.task.length)
this.task.forEach((func) => {
this.ball = func(this.ball)
})
}
reject(obj) {
if(this.status) return;
this.status="rejected";
this.ball=obj;
if(this.errTask)this.errTask(obj)
}
then(func,errFunc) {
this.task.push(func);
if(!this.errTask && errFunc) this.errTask=errFunc;
return this;
}
}
function fff(resolve, reject) {
reject("kkk err")
//resolve({ name: "kim" })
}
// test
var m = new MyPromise(fff)
var num=1;
m.then((obj) => { console.log(obj);num++; return { age: num } },(obj)=>console.log(obj))
这个MyPromise实现了基本的resolve和reject的功能,resolve和reject的状态一旦被设置就不能更改。
这里需要说明下构造函数中的setTimeout:
在js当中不考虑Worker的情况,一切都是单线程的,但是js引擎有着自己的一个任务队列,在js程序的运行过程中,会把一些任务逐个加入到队列中,然后依次运行他们。而setTimeout其实就是把一个任务在一定的延时时候添加到这个队列中,但是添加到队列中不代表会立即执行,而是要等到上一个任务执行结束。因此,这里的延时零秒的任务会等待当前的程序(最为队列的最前任务)执行完毕,才执行。而当前的程序已经调用了then向Promise的task队列中添加了要执行的函数,所以后面的resolve就能够用这些函数了。