Promise对象代表一个异步操作,有三种状态pending、fulfilled、rejected。具体是如何实现异步操作?
function myPromise(callback) {
// 用常量保存状态值,使用时有代码提示,不容易写错
const PENDING = 'pending'
const REJECTED = 'rejected'
const FULFLLED = 'fulfilled'
this.status = PENDING //初始状态值
this.msg //存储执行结果
this.thens = [] //存储多个then();xxx().then().then().then*()
this.func_error
// 通过 .then(成功回调,失败回调)接受用户传入的回调方法
this.then = function(func_success,func_error) {
this.thens.push(func_success)
this.func_error = func_error
// 返回this,支持链式写法;例如xxx().then().then().then()……
return this;
}
// 成功时触发,注意必须箭头函数 保持this指向
let resolve = (msg) => {
// 只有状态为pending时才能更改
if (this.status != PENDING) return;
this.status = FULFLLED //修改状态值
this.msg = msg;
// 触发终结方法
this.complete();
}
// 失败时触发,注意必须箭头函数,保持this指向
let reject = (msg) => {
if (this.status != PENDING) return;
this.status = REJECTED; //修改状态值
this.msg = msg
// 触发 终结 方法
this.complete()
}
// callback为用户传入的函数,即异步操作所在的位置
callback(resolve, reject);
// 统一出口:失败和成功 最终都调用此方法;便于维护
this.complete = () => {
if (this.status == FULFLLED) {
let first_time = true //首次
let res
// 考虑多个then()的情况
this.thens.forEach((item) => {
if (first_time) {
res = item(this.msg)
first_time = false
} else {
// 每次then都是上一次的返回值
res = item(res)
}
})
}
}
if (this.status == REJECTED && this.func_error) {
this.func_error(this.msg)
}
}
// 测试方法
console.log('运行中')
function demo() {
return new myPromise((resolve, reject) => {
setTimeout(() => {
let num = Math.round(Math.random() * 100)
if (num % 2 == 0) {
resolve(num)
} else {
reject(new Error("奇数" + num))
}
}, 300)
})
}
demo().then((res) => {
console.log("1" + res);
return res;
})
.then((res) => {
console.log(res / 2);
return res / 2;
})
.then((res) => {
console.log("3." + res);
return res / 2;
})
.then((res) => {
console.log("4." + res);
return res / 2;
})
.then((res) => {
console.log("5." + res);
return res / 2;
})
.catch((err) => console.log(err));