解决无catch回调promise失败会导致程序报错问题

发布于:2024-03-29 ⋅ 阅读:(17) ⋅ 点赞:(0)

使用场景: 在使用promise封装通用函数时(例如封装请求函数) 通常会对promise的失败情况做统一处理;为了某些时候,需要单独对失败做处理,就需要将失败抛出;但不需要对失败单独处理的时,又因失败抛出没有绑定失败回调函数导致程序报错

注意使用场景,因对失败情况做统一处理,避免开发过程中 因失败情况导致一些错误难以排查

平时我们封装的api请求

// 封装请求
function request(config) {
	return axios(config).then(res => {
		// 请求状态码不等于200,算请求失败
		if(res.code !== 200) return Promise.reject(res)
		// 对请求数据做再次封装
		return res
	}).catch(err => {
		// 对请求失败做处理
		// 例如:提示用户请求失败,或者返回到上一页
		return Promise.reject(err)
	})
}

使用request


// 请求使用
request({
	url: 'url'
}).then(res => {}) // 此时未绑定失败回调,在请求失败时程序会报错

此时请求失败控制台会有以下报错
在这里插入图片描述
你必须对请求失败做处理

request({
	url: 'url'
}).then(res => {}).catch(() => {}) // 但在接口封装里对失败做了处理,这里我们不需要再次处理失败

对与以上使用遇到的问题,对promise进行了再次封装

/**
 * 封装promise,解决无catch的promise异常,注意! 本身不具备promise的功能,成功和失败来自传入的promise实例
 * @param {Promise} promise 接受一个promise实例
 */
class MyPromise {
	promise
	_onRejected
	_onCatch
	constructor(promise) {
	  this.promise = promise
		this._onCatch = this.promise.catch(res => {
		  if(this._onRejected) {
				return Promise.reject(res)
			}
		})
	}
	then(onFulfilled, onRejected) {
		if(onFulfilled) return new MyPromise(this.promise.then(onFulfilled))
		return this.catch(onRejected)
	}
	catch(onRejected) {
		this._onRejected = onRejected
		// 不破坏promise 链式调用的特性,但又保证异常时程序不报错
		return new MyPromise(this._onCatch.catch(onRejected))
	}
	finally(onFinally) {
	  return new MyPromise(this.promise.finally(onFinally))
	}
}

使用示例

// 使用不会对promise的本身使用产生影响,注意! 本身不具备promise的功能,成功和失败来自传入的promise
new MyPromise(
	Promise.resolve('我是结果') // 这个promise 最后一次的catch也返回
).then(res => {
	console.log(1);
	return res
}).then(res => {
	console.log(2);
  return Promise.reject(res)
}).catch(err => {
	console.log(3);
  return Promise.reject(err)
}).catch(err => {
	console.log(4);
  return Promise.reject(err)
})
	// 或者这样
new MyPromise(Promise.resolve('我是结果').then(res => {
	console.log(1);
	return res
}).then(res => {
	console.log(2);
  return Promise.reject(res)
}).catch(err => {
	console.log(3);
  return Promise.reject(err)
}).catch(err => {
	console.log(4);
  return Promise.reject(err)
}))
// 输出结果 1,2,3,4


使用 myPromise 重新封装请求

function request(config) {
	return new MyPromise(axios(config).then(res => {
		// 请求状态码不等于200,算请求失败
		if(res.code !== 200) return Promise.reject(res)
		// 对请求数据做再次封装
		return res
	}).catch(err => {
		// 对请求失败做处理
		// 例如:提示用户请求失败,或者返回到上一页
		return Promise.reject(err)
	}))
}

使用请求

request({
	url: 'url'
}).then(res => {}) // 这里就不会报错了
request({
	url: 'url'
}).then(res => {
}).catch(() => {
// 这里可以对失败再次做处理
}) 
本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到