这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战
原生promise.then链式调用的特点
- 1.通过return传递结果
- 2.通过新的promise resolve结果
- 3.通过新的promise reject原因
- 4.then走了失败的回调函数后,在走then
- 5.then中使用throw new Error, 会走到下一个then失败的回调函数中去
- 6.用catch捕获异常 catch在Promise的源码层面上就是一个then, Catch也是遵循then的运行原则
从上面可以得出以下结论
- 成功的条件
- then return 普通的JavaScript value
- then return 新的promise成功态的结果 value
- 失败的条件
- then return 新的promise的失败态的原因 reason
- then 抛出了异常 throw new Error
- promise 链式调用
- return new Promise
let promise2 = promise.then((value) => {
// return 第一次返回的新的promise结果
}).then((value) => {
// return 第二次返回的新的promise结果
})
// 这两种是有区别的-----------------------
let promise2 = promise.then(() => {
// return 第一次返回的新的promise结果
})
// 第一次then返回的新的promise结果
promise2.then(() => {
})
实现promise.then
- 实现promise.then的链式调用
promise.then返回的是一个新的Promise,需要定义一个新的Promise实例。
- 在新的实例里面进行处理,实例的resolve和reject有一个返回值x,x可能是一个普通的值或者一个新的Promise,所以需要对x进行处理,定义函数resolvePromise
- 也需要对异常进行处理。 详细的需求可见Promise/A+, 按照文档规范来 The Promise Resolution Procedure
/**
* @description 判单x是否是一个promise,如果是promise,需要进行特殊的处理,如果不是,需要resolve,reject
* @param {*} promise2
* @param {*} x
* @param {*} resolve
* @param {*} reject
* @return {*}
*/
function resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('TypeError: Chaining cycle detected for promise #<MyPromise>'))
}
let called = false; // 是否调用
if ((typeof x === 'object' && x !== null) || typeof x === 'function') {
try {
let then = x.then // throw error
// 通过判断then是不是一个function来判断是否是promise
if (typeof then === 'function') { // promise
then.call(x, (y) => {
if (called) return
called = true
// 递归调用,处理一直resolve新的promise实例
resolvePromise(promise2, y, resolve, reject) // 处理问题1
}, (r) => {
if (called) return
called = true
reject(r)
})
} else {
resolve(x) // 如果不是一个promise,直接resolve
}
} catch (e) {
if (called) return
called = true
reject(e)
}
} else {
resolve(x)
}
}
详细代码见github地址