Promise是一种抽象异步处理对象,Promise类的构造函数中使用一个参数,参数值为一个回调函数。该回调函数又使用两个参数,参数值分别为两个回调函数(resolve,reject),如果执行成功则调用resolve回调函数,否则执行reject回调函数
如下代码,promise是一个类,所有我们可以用构造函数来进行实现,promise中可以传入一个参数,参数值为一个函数((resolve,reject) => {}),其参数值又可以传入两个参数,参数值为resolve和reject函数,则我们实现的promise需要接收一个参数,其参数为立即执行函数,并实现两个参数(resolve和reject), 因promise从初状态pending跳转到另一个状态后,就不可改变,所以用status存放状态,在resolve和reject实现函数中,每次都加个判断,只有是初状态pending才会执行
let that;
function Promise(executor) {
that = this;
this.status = "pending"; // 保存promise中的状态,最初为pending
this.success = undefined; // 存成功状态传入的值
this.err = undefined; // 存失败状态传入的值
// 以下两个数组是 当new Promise对象时,成功(resolve) 或者失败(reject) 存放在异步操作,
// 例如(放在定时器中),需要先把.then(回调函数) 先存放在数组内,
this.resolveArray = [];
this.rejectArray = [];
let resolve = val => {
setTimeout(() => {
if (this.status === "pending") {
this.status = "fulfilled";
this.success = val;
// 遍历数组是为了查看promise对象中是否有异步操作
this.resolveArray.forEach(value => {
value();
})
}
})
}
let reject = val => {
setTimeout(() => {
if (this.status === "pending") {
this.status = "rejected";
this.err = val;
// 遍历数组是为了查看promise对象中是否有异步操作
this.rejectArray.forEach(value => {
value();
})
}
})
}
// 若new promise 中throw出错误,则执行catch里面
try {
executor(resolve, reject);
} catch (e) {
reject(e);
}
}
Promise.prototype.then = (resolve, reject) => {
let res = undefined;
if (that.status === "fulfilled") {
resolve(that.success);
}
if (that.status === "rejected") {
res = reject(that.err);
}
// 没有走成功或失败的回调函数 以下是因为代码中有异步操作,所以状态还是pending
if (that.status === "pending") {
that.resolveArray.push(() => {
resolve(that.success);
});
that.rejectArray.push(() => {
res = reject(that.err);
});
}
}
//promise类中无定时器
let p = new Promise((resolve, reject) => {
resolve("success");
})
p.then(data => {
console.log(data);
}, err => {
console.log(err);
})
运行结果如下:
// promise中有定时器
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success');
console.log("666");
}, 1000)
})
p.then(data => {
console.log(data);
}, err => {
console.log(err);
})
运行结果如下:
说明:在定时器中因 console是同步任务,所以是先输出666,再输出success,这也是我们前面在resolve和reject函数中加入定时器的原因,将其置于宏任务中
// 将then函数修改如下
Promise.prototype.then = (resolve, reject) => {
let res = undefined; // res为保存上一步then返回的值
let flag = 0; // 当flag为0 时,表示返回成功的回调函数,1表示返回失败的回调函数
if (that.status === "fulfilled") {
try {
res = resolve(that.success);
} catch (e) {
flag = 1;
res = e;
}
}
if (that.status === "rejected") {
try {
res = reject(that.err);
} catch (e) {
flag = 1;
res = e;
}
}
// 没有走成功或失败的回调函数
if (that.status === "pending") {
that.resolveArray.push(() => {
try {
res = resolve(that.success);
} catch (e) {
flag = 1;
res = e;
}
});
that.rejectArray.push(() => {
try {
res = reject(that.err);
} catch (e) {
flag = 1;
res = e;
}
});
}
// 判断上一步返回的是否为promise对象,若是直接返回,如果不是,则创建一个promise对象
if(isPromise(res)){
return res;
}
return new Promise((resolve,reject) => {
if(flag){
reject(res);
}else{
resolve(res);
}
})
}
接下来将创建一个链式的then,代码如下
let p = new Promise((resolve, reject) => {
resolve("success");
})
p.then(data => {
console.log(data);
}, err => {
console.log(err);
}).then(data => {
console.log(data);
})
运行结果如下:
说明:因上一步then没有返回值,则默认返回undefined,所以结果打印出 success和undefined
// catch为失败的回调函数
Promise.prototype.catch = (reject) => {
return that.then(undefined,reject);
}
let p = new Promise((resolve, reject) => {
reject("success");
})
p.catch(err => {
console.log(err + " err");
})
运行结果如下:
以上为简易的promise实现,还有一些不足之处,后续会再改正!!!!!!