Promise代码
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
// 因为状态经常使用所以设置为常量
function resolvePromise(Promise2, x, resolve, reject) {
if (Promise2 === x) { //防止Promise重复调用
reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
x.then(resolve, reject)
} else {
resolve(x)
}
}
class MyPromise {
//传进执行器,执行器立即执行
constructor(executor) {
executor(this.resolve, this.reject)
}
//Promise的状态
status = PENDING
//成功的值
value = undefined
//失败的值
reason = undefined
scb = []
fcb = []
//箭头函数使this指向指向当前Mypromise
resolve = value => {
if (this.status != PENDING) return
this.status = FULFILLED
//保存成功之后的值
this.value = value
while (this.scb.length) this.scb.shift()()
}
reject = reason => {
if (this.status != PENDING) return
this.status = REJECTED
//保存失败之后的值
this.reason = reason
// this.fcb && this.fcb(reason)
while (this.fcb.length) this.fcb.shift()()
}
then(scb, fcb) {
scb = scb ? scb : value => value; //使then方法的参数变为可选参数
fcb = fcb ? fcb : reason => { throw reason };
let Promise2 = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
setTimeout(() => { //使用setTimeOut来拿到Promise的值
try { //用来捕获错误
let x = scb(this.value)
// 判断x值是普通值还是myPromise对象,分别做处理。
// 因为三个判断都需要可以抽取为一个函数
resolvePromise(Promise2, x, resolve, reject)
} catch (error) {
reject(error)
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => { //使用setTimeOut来拿到Promise的值
try { //用来捕获错误
let x = fcb(this.reason)
// 判断x值是普通值还是myPromise对象,分别做处理。
// 因为三个判断都需要可以抽取为一个函数
resolvePromise(Promise2, x, resolve, reject)
} catch (error) {
reject(error)
}
}, 0)
// let x = fcb(this.reason)
// reject(x)
} else {
//等待 存储回调
// this.fcb = fcb;
// this.scb = scb;
this.scb.push(() => {
setTimeout(() => { //使用setTimeOut来拿到Promise的值
try { //用来捕获错误
let x = scb(this.value)
// 判断x值是普通值还是myPromise对象,分别做处理。
// 因为三个判断都需要可以抽取为一个函数
resolvePromise(Promise2, x, resolve, reject)
} catch (error) {
reject(error)
}
}, 0)
});
this.fcb.push(() => {
setTimeout(() => { //使用setTimeOut来拿到Promise的值
try { //用来捕获错误
let x = fcb(this.reason)
// 判断x值是普通值还是myPromise对象,分别做处理。
// 因为三个判断都需要可以抽取为一个函数
resolvePromise(Promise2, x, resolve, reject)
} catch (error) {
reject(error)
}
}, 0)
});
}
})
return Promise2
}
static all(array) {
let result = [];
let index = 0; //解决空值,因为要等待异步操作的结果
return new MyPromise((resolve, reject) => {
function addData(key, value) {
result[key] = value
index++
if (index === array.length) {
resolve(result)
}
}
for (let i = 0; i < array.length; i++) {
let current = array[i]
if (current instanceof MyPromise) {
//是Promise对象
// addData(i, current.then())
current.then(value => addData(i, value), reason => reject(reason))
} else {
//是普通值
}
}
})
}
static resolve(value) {
if (value instanceof MyPromise) return value
return new MyPromise(resolve => resolve(value))
}
catch (fcb) {
return this.then(undefined, fcb)
} finally(callback) {
return this.then(value => {
//调用Mypromise.resolve是等待上一个执行完成
return MyPromise.resolve(callback()).then(() => value)
}, reason => {
return MyPromise.resolve(callback()).then(reason => { throw reason })
})
}
}
module.exports = MyPromise;
// module.exprots = MyPromise;
逻辑与步骤
/**
* ——————————核心逻辑——————————
* 1.Promise是一个类 在执行这个类的时候,需要传递一个执行器,执行器会立即执行
* 2.Promise三种状态 pending fulfilled rejected pending
* pending->fulfilled
* pending->rejected
* 3.Promise 中resolve和reject来更改状态
* 4.then 方法内部判断,then方法应该是被定义原型对象上
* 5.需要存储成功或者失败的原因
* ————————————异步逻辑————————————————
* -then方法存储值,resolve和reject来判断是否有值
* 存储失败回调和成功回调存储起来
* ————————————多次调用then————————————
* 将存储的属性变为一个数组
* ————————————链式调用——————————————
* then方法返回的是一个myPromise对象,并需要判段传进的是Mypromise对象或者普通值
* then方法链式调用并识别Promise对象自返回(防止Promise的循环调用)
* ————————————捕获错误——————————————
* 1,try catch
* 2.setTimeout 来拿到当前实例返回结果
*
* ————————————then可选参数——————————
* then方法中判断
* ————————————myPromise.all方法的实现————————
* 1.传入一个数组。元素有Promise 和普通值
* 2.有一个失败最终都失败
* 3.all方法是静态方法
* 4.等待异步操作结果,防止空值现象
* ————————————myPromise.resolve()——————
* 将一个值转换为Promise 对象 如果是Promise对象直接返回该对象
* ————————————Promise。fianlly方法——————
* 无论成功失败,finally方法都会调用
* 处理下一个等待上一个执行完成
*/