手写 Promise 源码之 catch 方法实现
2022/6/28 14:23:41
本文主要是介绍手写 Promise 源码之 catch 方法实现,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
目录- 手写 Promise 源码之 catch 方法实现
- 场景
- 代码实现
手写 Promise 源码之 catch 方法实现
场景
const MyPromise = require('./myPromise') function p1() { return new MyPromise((resolve, reject) => { setTimeout(() => { resolve('p1') }, 2000) }) } function p2() { return new MyPromise((resolve, reject) => { // reject('p2 reject') resolve('p2 resolve') }) } p2() .then(value => console.log(value)) .catch(reason => console.log(reason))
代码实现
关键代码
catch(failCallback) { return this.then(undefined, failCallback) }
const PENDING = 'pengding' // 等待 const FULFILLED = 'fulfilled' // 成功 const REJECTED = 'rejected' /// 失败 class MyPromise { constructor(exectuor) { // 捕获执行器中的错误 try { exectuor(this.resolve, this.reject) } catch (e) { this.reject(e) } } // promise 状态 status = PENDING // 成功之后的值 value = undefined // 失败之后的原因 reason = undefined // 成功回调 successCallback = [] // 失败回调 failCallback = [] // 此处的箭头函数是为了使 this 指向该函数的实例对象 resolve = value => { // 如果状态不是等待,阻止程序向下执行 if (this.status !== PENDING) return // 将状态更改为成功 this.status = FULFILLED // 保存成功之后的值 this.value = value // 判断成功回调是否存在,如果存在就调用 // this.successCallback && this.successCallback(this.value) while (this.successCallback.length) { this.successCallback.shift()() } } reject = reason => { // 如果状态不是等待,阻止程序向下执行 if (this.status !== PENDING) return // 将状态更改为失败 this.status = REJECTED // 保存失败后的原因 this.reason = reason // 判断失败回调是否存在,如果存在就调用 // this.failCallback && this.failCallback(this.reason) while (this.failCallback.length) { this.failCallback.shift()() } } then(successCallback, failCallback) { successCallback = successCallback ? successCallback : value => value failCallback = failCallback ? failCallback : reason => { throw reason } // 实现链式调用 let promise2 = new MyPromise((resolve, reject) => { // 判断状态 if (this.status === FULFILLED) { // 解决 resolvePromise(promise2, x, resolve, reject) 获取不到 promise2 的问题 setTimeout(() => { try { let x = successCallback(this.value) // 判断 X 的值是普通值还是 promise 对象 // 如果是普通值,直接调用 resolve // 如果是 promise 对象,查看 promise 对象返回的结果 // 再根据 promise 对象返回的结果,决定调用 resolve 还是调用 reject resolvePromise(promise2, x, resolve, reject) } catch (e) { reject(e) } }, 0) } else if (this.status === REJECTED) { setTimeout(() => { try { let x = failCallback(this.reason) // 判断 X 的值是普通值还是 promise 对象 // 如果是普通值,直接调用 resolve // 如果是 promise 对象,查看 promise 对象返回的结果 // 再根据 promise 对象返回的结果,决定调用 resolve 还是调用 reject resolvePromise(promise2, x, resolve, reject) } catch (e) { reject(e) } }, 0) } else { // 等待 // 将成功回调和失败回调存储起来 this.successCallback.push(() => { setTimeout(() => { try { let x = successCallback(this.value) // 判断 X 的值是普通值还是 promise 对象 // 如果是普通值,直接调用 resolve // 如果是 promise 对象,查看 promise 对象返回的结果 // 再根据 promise 对象返回的结果,决定调用 resolve 还是调用 reject resolvePromise(promise2, x, resolve, reject) } catch (e) { reject(e) } }, 0) }) this.failCallback.push(() => { setTimeout(() => { try { let x = failCallback(this.reason) // 判断 X 的值是普通值还是 promise 对象 // 如果是普通值,直接调用 resolve // 如果是 promise 对象,查看 promise 对象返回的结果 // 再根据 promise 对象返回的结果,决定调用 resolve 还是调用 reject resolvePromise(promise2, x, resolve, reject) } catch (e) { reject(e) } }, 0) }) } }) return promise2 } finally(callback) { return this.then(value => { // callback() // return value return MyPromise.resolve(callback()).then(() => value) }, reason => { // callback() // throw reason return MyPromise.resolve(callback()).then(() => { throw reason }) }) } catch(failCallback) { return this.then(undefined, failCallback) } 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 对象 current.then(value => addData(i, value), reason => reject(reason)) } else { // 普通值 addData(i, array[i]) } } }) } static resolve(value) { if (value instanceof MyPromise) { return value } return new MyPromise(resovle => resovle(value)) } } function resolvePromise(promise2, x, resolve, reject) { // then 链式调用,promise 对象返回其自己(循环调用) if (promise2 === x) { return reject(new TypeError('Chaining cycle detected for promise #<Promise>')) } if (x instanceof MyPromise) { // promise 对象 // x.then(value => resolve(value), reason => reject(reason)) // 简化成如下代码 x.then(resolve, reject) } else { // 普通值 resolve(x) } } // node 环境下导出 module.exports = MyPromise
这篇关于手写 Promise 源码之 catch 方法实现的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享