手写promise原理系列五:Promise.prototype.catch方法的封装与异常穿透,promise.catch的用法

在这里插入图片描述

在上一篇文章中手写封装了 then 方法,这一篇继续前行,可以在原有封装 then 方法的前提下封装一个 catch 方法,非常简单。

catch 方法接受一个参数,就是失败时的回调,而 then 方法接受两个参数,第二个参数为失败时的回调,那可不可以只使用 then 方法的第二个参数呢?

catch 的功能实现:

  • 接受一个参数:onRejected
  • 返回一个 promise 对象
  • 异常穿透

先来看一下 catch 的使用方式:

let p = new Promise((resolve, reject) => {
    
    
	reject("NO");
})
p.catch(reason => {
    
    
	console.log(reason);  // "NO"
})

Promise.prototype.catch 代码封装如下

Promise.prototype.catch = function(onRejected){
    
    
	// this就是实例对象 promise
	return this.then(undefined, onRejected);
}

上面代码 then 中第一个参数使用 undefined 占位,就像我们使用 call 以及 apply 时,无绑定 this 形式一样,例如:

fn.call(null, 1, 2, 3)
fn.apply(null, [1, 2, 3])

catch 的链式调用使用方式:

let p = new Promise((resolve, reject) => {
    
    
	reject("NO");
})
// 这里的第一个then方法没有传参,且后面每一个then方法只传了一个回调函数
p.then()
 .then(value=> {
    
    
	console.log(value);
}).then(value=> {
    
    
	console.log(value);
}).catch(reason => {
    
    
	console.log(reason);
})

在上面代码中的第一个 then 方法中没有传递回调函数,这时候咱们封装的 then 方法肯定报错,程序无法执行,因为不传参数,相当于传递两个 undefined 值,undefined 值无法进行函数调用,因为 then 方法内部默认是传递函数作为参数的。这时候就需要在 then 方法中添加未传值时的处理,当 then 中无值或只有一个值时,我们给他一个自定义生成的函数,这样成功和错误的结果会向下传递,不至于报错而终止程序。

还得修改then方法:

Promise.prototype.then = function(onResolved, onRejected){
    
    
	// 若无 onResolved,则自定义一个 onResolved函数,并传递成功结果
	if (typeof onResolved !== "function") {
    
    
		onResolve = value => value;
	}
	// 若无 onRejected,则自定义一个 onRejected函数,并传递失败结果
	if (typeof onRejected !== "function") {
    
    
		onRejected = (reason) =>{
    
    
			throw reason; // 抛出错误,这就是异常穿透,直到遇到 try...catch...才会停止。
		}
	}
	return new Promise((resolve, reject) => {
    
    
		// ...其他代码...
	})
}

当 then 中第二个参数 onRejected 回调函数为 undefined 时,给他一个自定义函数,然后一直抛出错误,让错误可以一直向下传递,直到遇到try...catch...捕获错误,这种通过多层级获取抛出错误的方式就是异常穿透

下图为上面代码的图示理解,我尽力了。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/ThisEqualThis/article/details/129482365
今日推荐