关于Promise.catch()错误捕获机制的理解
Promise.prototype.catch() ()错误捕获机制的理解描述:关于catch方法MDN的描述是这样的:Internally calls Promise.prototype.then on the object upon which is called, passing the parameters undefined and the onRejected handler rece
描述:
- 关于
catch
方法MDN的描述是这样的:
Internally calls Promise.prototype.then on the object upon which is called, passing the parameters undefined and the onRejected handler received; then returns the value of that call (which is a Promise )。这里说到 :
-
.catch
方法在内部也是调用的Promise.prototype.then
方法中的reject
状态下的方法,也就是callingobj.catch(onRejected)
内部callsobj.then(undefined, onRejected)
; -
它返回了一个失败的
promise
,
以及返回一个参数作为一个失败理由。值得注意的是这里返回的是一个已定型的promise
,这个过程是promise
从pending
到reject
的改变过程。p.then((val) => console.log('fulfilled:', val)) .catch((err) => console.log('rejected', err)); // 等同于 p.then((val) => console.log('fulfilled:', val)) .then(null, (err) => console.log("rejected:", err));
-
如果
Promise
状态已经变成resolved
,再抛出错误是无效的。const promise = new Promise(function(resolve, reject) { resolve('ok'); throw new Error('test'); //会被忽略,不会被捕获,等于没有抛出 }); promise .then(function(value) { console.log(value) }) .catch(function(error) { console.log(error) }); // ok
这里很好理解,就是catch
是从pending
到reject
的状态改变,但是一个promise一旦resolve以后,状态就凝固了,无法再发生变化,因此会被忽略。
错误捕获
1. try...catch
捕获错误
先来看看try...catch
语句的错误捕获机制:当多层嵌套try...catch
出现时,内部的错误抛出会被最近一个catch
,直到最外层。当错误被内部的catch
捕获后,就失效了。
try {
try {
throw new Error("oops");
}
catch (ex) {
console.error("inner", ex.message); //catch try抛出的 错误
}
finally {
console.log("finally");
}
}
catch (ex) {
console.error("outer", ex.message); //这里的代码不执行
}
// Output:
// "inner" "oops"
// "finally"
再次抛出错误
try {
try {
throw new Error("oops");
}
catch (ex) {
console.error("inner", ex.message);
throw ex; //这里已经捕获到了异常,这个异常就失效了;如果这里不重新throw ex,外面的catch感知不到这里的异常的,即外层的catch{}不会执行
}
finally {
console.log("finally");
}
}
catch (ex) {
console.error("outer", ex.message); //捕获 throw ex;
}
// Output:
// "inner" "oops"
// "finally"
// "outer" "oops"
2. promise
捕获错误
promise
错误捕获和try...catch
一样会冒泡到外层。
promise
的错误抛出后会一直传递到最外层,直到被捕获;当catch
捕获错误以后,返回的还是一个promise对象,可以继续链式调用。
const p1 = new Promise((resolve, reject) => {
setTimeout(() => resolve('成功'), 3000)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => reject(new Error('失败了')), 3000)
})
p1.then(function (post) {
return p2
})
.then((resolve) => {
//这里的代码不会执行
console.log('p2 reject 第二个then执行了')
return `第二个then的返回值`
})
.catch((e) => {
console.log(e, '=====first error')
})
.then((resolve) => {
console.log('第三个then执行了,接收到的返回值为:', resolve)
})
.catch((e) => console.log(e, '=====error'))
// Error: 失败了 at eval (test.js?33a7:92) "=====first error"
// console.log('第三个then执行了,接收到的返回值为:', resolve)
如果.then()
方法后面没有catch
方法,后面紧跟着的链式调用的.then()
不会执行。
p1.then(function (post) {
return p2
})
.then((resolve) => {
//这里的代码不会执行
console.log('p2 reject 第二个then执行了')
return `第二个then的返回值`
})
.then((resolve) => {
//这里的代码不会执行
console.log('第三个then执行了,接收到的返回值为:', resolve)
})
.catch((e) => console.log(e, '=====error'))
// Error: 失败了 at eval (test.js?33a7:92) "=====error"
3. 区别:
prmise
跟传统的try/catch
代码块不同的是,如果没有使用catch()
方法指定错误处理的回调函数,Promise
对象抛出的错误不会传递到外层代码,即不会有任何反应。
try {
try {
throw new Error("oops");
} catch (ex) {
// console.error('inner', ex.message)
// throw ex
} finally {
console.log("finally");
}
} catch (ex) {
console.error("outer", ex.message); // 捕获 throw ex;
}
// finally
上面的代码,catch
代码块捕获了错误,但是进行错误处理,浏览器也不会自动抛出错误,会跳过这段错误。
但如果是promise
则会传递未捕获的错误,浏览器会自动抛错。
p1.then(function (post) {
return p2
})
.then((resolve) => {
console.log('p2 reject 第二个then执行了')
return `第二个then的返回值`
})
// Uncaught (in promise) Error: 失败了
// at eval (test.js?33a7:92)
更多推荐
所有评论(0)