难点1:then的状态接受
1.如果promise内部回调没有执行resolve()或者reject()那么then将不执行,并分别将then中的两个回调行参then(()={},()=>{})存储数组中,但不会立即执行,并且promise的状态处于pending
2.如果promise内部回调执行了resolve()又执行了reject(),则当中先执行的会被执行,第二个不会被执行比如:
new Promise((resolve,reject)=>{
resolve(1) // 执行,并将状态更改为 fulfilled
reject(1)// 不会执行,因为一旦状态发生变化,将不会执行下
})
同时.then函数会根据相应的状态执行onResolve或onReject,对应的一个回调。
3.如果promise函数内部回调执行了reject,
而.then函数没有定义onReject,则此时会报错,并且promise状态为rejected;
而.then函数定义了onReject,则此时正常执行onReject,当时状态值为resolve;
4..then函数返回值是个新promise,则promise的状态该新promise状态
返回值为非promise,则promise的状态为fulfilled
难点2:then的俄罗斯套娃
then函数套娃部分
if (result instanceof MyPromise) {
result.then(nextResolve, nextReject);
}
因为当前then返回的是一个promise,而promise并不能作为实际的resolve的value值,因此再执行一遍then,
此时传入then中的nextResolve回调,当中必定没有任何返回值,因此会走到
else {
// 将上一个promise成功回调执行的结果传递给下一个promise成功的回调
nextResolve(result);
}
nextResolve(result)相当于执行了resolve函数,resolve的value值变得正常
then函数的完整代码
then(onResolved, onRejected) {
return new MyPromise((nextResolve, nextReject) => {
// 1.判断有没有传入成功的回调
if (this._isFunction(onResolved)) {
// 2.判断当前的状态是否是成功状态
if (this.status === FULFILLED) {
try {
// 拿到上一个promise成功回调执行的结果
let result = onResolved(this.value);
// console.log("result", result);
// 判断执行的结果是否是一个promise对象
if (result instanceof MyPromise) {
result.then(nextResolve, nextReject);
} else {
// 将上一个promise成功回调执行的结果传递给下一个promise成功的回调
nextResolve(result);
}
} catch (e) {
nextReject(e);
}
}
}
// 1.判断有没有传入失败的回调
// if(this._isFunction(onRejected)){
try {
// 2.判断当前的状态是否是失败状态
if (this.status === REJECTED) {
let result = onRejected(this.reason);
if (result instanceof MyPromise) {
result.then(nextResolve, nextReject);
} else {
nextResolve(result);
}
}
} catch (e) {
nextReject(e);
}
// }
// 2.判断当前的状态是否是默认状态
if (this.status === PENDING) {
if (this._isFunction(onResolved)) {
// this.onResolvedCallback = onResolved;
this.onResolvedCallbacks.push(() => {
try {
let result = onResolved(this.value);
if (result instanceof MyPromise) {
result.then(nextResolve, nextReject);
} else {
nextResolve(result);
}
} catch (e) {
nextReject(e);
}
});
}
// if(this._isFunction(onRejected)){
// this.onRejectedCallback = onRejected;
this.onRejectedCallbacks.push(() => {
try {
let result = onRejected(this.reason);
if (result instanceof MyPromise) {
result.then(nextResolve, nextReject);
} else {
nextResolve(result);
nextReject();
}
} catch (e) {
nextReject(e);
}
});
// }
}
});
}
完整示例代码实现目标:
1.promise回调:
回调内部resolve和reject只会执行第一个,并且只改变一次状态;
回调内部可以写异步setTimeout函数,并延迟执行;
回调内部可以捕获throw错误,并通过reject传递;
2.then回调
若状态为 fulfilled,则执行成功回调;
若状态为 rejected,则执行失败回调;
3.then回调的返回结果
若回调返回一个新的prmoise,则then函数返回该的promise状态与新promise一致;
若回调放回一个非promise,则函数内部自动返回一个新的promise且状态为"fulfilled";
const FULLFILLED = 'fulfilled'
const REJECTED = 'rejected'
const PENDING = 'pending'
class MyPromise {
constructor(cb) {
this.status = PENDING
this.resolveCallbacks = []
this.rejectCallbacks = []
this.value = ''
this.reason = ''
// 用户直接在外部回调写throw,此处需要捕获
try {
cb(this._resolve.bind(this), this._reject.bind(this))
} catch(err) {
this._reject.call(this,err)
}
}
_resolve(value) {
if (this.status !== PENDING) return
this.status = FULLFILLED
this.value = value
// 需求是,then函数一定是在promise的回调执行完”之后“再执行。
/*
-要做到这点,需要如下:
1.then函数内判断状态为pending时候不要立即执行回调,而是将回调存储在相应的数组中
2._resolve函数执行状态变更完毕后,再去执行对应的then函数回调。
综上,能顺利满足需求
-例子:
若promise回调存在定时器,则定时器执行时候,在这之前then中的函数由于pending状态,早已手动加入数组中,
直到_resolve执行时候.then中的函数才会被执行
*/
//
this.resolveCallbacks.forEach(fn=>fn(this.value))
}
_reject(reason) {
if (this.status !== PENDING) return
this.status = REJECTED
this.reason = reason
// promise回调存在定时器的请
this.rejectCallbacks.forEach(fn=>fn(this.valureasone))
}
_isFunction(fn) {
if (typeof fn === 'function') {
return true
}
return false
}
then(onResolve, onReject) {
// 优化,不传递参数时 直接返回this
if (!this._isFunction(onResolve)) return this
return new MyPromise((nextResolve, nextReject) => {
// 不执行,只存储回调
if (this.status === PENDING) {
if (this._isFunction(onResolve)) {
this.resolveCallbacks.push(() => {
try {
// 保存回调结果
let result = onResolve(this.value)
if (result instanceof MyPromise) {
result.then(nextResolve, nextReject)
} else {
nextResolve(result)
console.log("执行了then中的回调")
\
}
} catch (err) {
nextReject(err)
}
})
} else if (this._isFunction(onReject)) {
this.rejectCallbacks.push(() => {
try {
// 保存回调结果
let result = onReject(this.reason)
if (result instanceof MyPromise) {
result.then(nextResolve, nextReject)
} else {
nextResolve(result)
}
} catch (err) {
nextReject(err)
}
})
} else {
nextResolve(this.value)
}
return
\
}
\
if (this.status === FULLFILLED) {
try {
// 保存回调结果
let result = onResolve(this.value)
if (result instanceof MyPromise) {
result.then(nextResolve, nextReject)
} else {
nextResolve(result)
}
} catch (err) {
nextReject(err)
}
}
\
// 特别注意:在then里面就是执行reject,this.status的状态也是fulfilled
if (this.status === REJECTED) {
if (this._isFunction(onReject)) {
try {
// 保存回调结果
let result = onReject(this.reason)
if (result instanceof MyPromise) {
result.then(nextResolve, nextReject)
} else {
nextResolve(result)
}
} catch (err) {
nextReject(err)
}
} else {
// nextReject(this.reason)
// setTimeout(()=>{
// throw new Error('Uncaught (in promise)' + this.reason)
// })
// return this
}
}
\
})
}
catch(onRejected) {
return this.then(undefined, onRejected);
}
}