解决async/await中promise返回reject报错的问题,浅谈js异常捕获的历程

javascript我觉得印象深刻的两大特点,单线程和异步,单线程不说了,今天来说下异步吧,这星期我碰到的一个问题,async/await中promise返回reject报错的问题,这是我以前没有留意到的,异步编程步步都是坑,正常的思维方式应该是同步的,而异步思维没经过训练,很容易犯错,我想啊,promise用async,await优化,不仅是为了更优雅的书写,和阅读,通过优化把异步代码写成同步,也是为了更加符合人正常的思维方式吧

本文的叙述路线:

先从es5的异常捕获开始-------->再到es6Pomise()异常的处理------>最后来谈谈通过async,await优化promise后reject的问题(这是重点)

ES5的异常捕获:

正常的异常捕获:

	try {
			throw new Error(3)
		} catch(e) {
			console.log(e)
		}

在这里插入图片描述
这是ok的,但是如果try中出现了异步代码呢?

		try {
			setTimeout(function() {
				throw new Error("error")
			}, 1000)
		} catch(e) {
			console.log(e)
		}

在这里插入图片描述

可以看到,并没有捕获到

原因:

以上例子中第二个try catch捕获不到错误,因为try catch是同步的,执行到setTimeout时把它放到了异步任务队列里(setTimeout是异步的)没有立即执行setTimeout就往下走了同步任务执行完再回头把异步任务队列里的setTimeout回调函数拿出来执行就报错了。

要捕获到异常,必须在throw new Error的直接外层用try catch包起来才行:

	setTimeout(() => {
			try {
				throw new Error("error")
			} catch(e) {
				console.log(e);
			}
		}, 1000);

ES6 promise方式的错误捕获:

这是异步任务完成调用resolve的做法:

	function fn() {
			return new Promise((resolve, reject) => {
				setTimeout(() => {
					resolve("ok")
				}, 1000)
			})
		}

			fn()
			.then(res => {
				console.log(res)
			})

在这里插入图片描述
这是异步任务失败调用reject的捕获异常方法

		function fn() {
			return new Promise((resolve, reject) => {
				setTimeout(() => {
					reject("error")
				}, 1000)
			})
		}

			fn()
			.catch(err => {
				console.log(err)
			})

在这里插入图片描述

最重要的部分来了

ES6通过async,await优化promise时的异常捕获:

先来看问题,通过async,await的方式去优化promise只能接收到成功resolve()的结果对于reject()的结果是会报错的

先看下正常resolve() 的情况:正常的

		function fn() {
			return new Promise((resolve, reject) => {
				setTimeout(() => {
					resolve("ok")
				}, 1000)
			})
		}

		async function go() {
			let res = await fn()
			console.log(res)
		}

		go()

在这里插入图片描述
改成reject()返回结果:发现报错了

		function fn() {
			return new Promise((resolve, reject) => {
				setTimeout(() => {
					reject("error")
				}, 1000)
			})
		}

		async function go() {
			let res = await fn()
			console.log(res)
		}

		go()

在这里插入图片描述

解决async/await中的promise返回错误reject的问题,及错误捕获:

方式一:async/await已经把异步代码优化成了同步代码,同步代码可以通过try,catch捕获到异常

function fn() {
			return new Promise((resolve, reject) => {
				setTimeout(() => {
					reject("error")
				}, 1000)
			})
		}

		async function go() {
			try{
				let res = await fn()
			}catch(e){
				console.log(e)
			}
		}

		go()

在这里插入图片描述

方式二:通过返回一个pending状态的结果,中断promise链的方式处理错误

function fn() {
			return new Promise((resolve, reject) => {
				setTimeout(() => {
					//reject("error")
					return new Promise(() => {}) //中断promise链
				}, 1000)
			})
		}

		async function go() {
			let res = await fn()
			console.log(e)
		}

		go()

此时res什么都没接收到,不会出现reject报错的问题了
在这里插入图片描述

我个人更偏向于方法二处理async/await中的promise返回错误reject的问题,够优雅,不会出现多余且不好看的代码
  • 22
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

codingWeb

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值