最近太忙 好久沒有跟新了. 給自己留個(gè)坑,說一下js 中的錯(cuò)誤處理.
分為三塊吧.
第一:普通的js中 錯(cuò)誤處理.
第二: promise 中的錯(cuò)誤處理
第三: async 中的錯(cuò)誤處理
第一: 普通的js 的錯(cuò)誤處理?
?說普通是因?yàn)楸容^簡(jiǎn)單,算一個(gè)知識(shí)點(diǎn)沒有太多啥說的,大家找找資料比較齊全
https://www.sitepoint.com/exceptional-exception-handling-in-javascript/
try{
? ? ...? ? //異常的拋出}
catch(e){
? ? ...? ? //異常的捕獲與處理}
finally{
? ? ...? ? //結(jié)束處理}
第二: promise 中的錯(cuò)誤處理
在promise 中處理錯(cuò)誤,我們通常也是去try catch,但是 只能catch 到同步的錯(cuò)誤,如果是異步的,比如我們settimeout一下其實(shí)是catch不到的.來個(gè)栗子:
var promise = new Promise(function(resolve, reject){
? ? setTimeout(function(){
? ? ? ? throw new Error('test')
? ? }, 0)
? ? resolve('ok'); //輸出
});
promise
? ? .then(function(value){ console.log(value) })
? ? .catch(()=> console.log('err'))
可以看到,只輸出了ok,然后瀏覽器捕獲的錯(cuò)誤,catch并沒有拿到.
然后看看我們使用reject 來拋出錯(cuò)誤
可以看到,reject 會(huì)不停的返回到下一個(gè),但是并不會(huì)被catch 到.如果我們?cè)囋噒hrow 一個(gè)error呢?
通過一層層throw 在catch 里面我們是可以拿到的,疑問來來, 如果是通過 異步promise 里面reject 能catch 到么?
依然是可以拿到的.
好啦最后總結(jié)一下吧.在promise 中, 如果使用reject 錯(cuò)誤,必須要再每個(gè)then函數(shù)中throw 出去,不然在catch中無法拿到.其實(shí)我們不需要再次的throw ,在promise 正常catch 就好,比如在上面的異步中我們r(jià)eject一下在最后就能catch到. 需要注意的一點(diǎn)就是:promise 中的錯(cuò)誤是不會(huì)影響外層的運(yùn)行,window.onerror 也是無法檢測(cè)到的.
第三: async 中的錯(cuò)誤處理
async用起來確實(shí)方便很多,promise 導(dǎo)致整段代碼都是promise 的then ,如果判斷太多導(dǎo)致代碼邏輯復(fù)雜難以維護(hù),而且每個(gè)then 都有自己的作用域,如果要貢獻(xiàn)數(shù)據(jù) 通常要在外層新建一個(gè).
直接貼代碼吧,看看async 正常處理異步的方式
const f = () => {
? return new Promise((resolve, reject) => {
? ? setTimeout(() => {
? ? ? reject(234);
? ? }, 2000);
? });
};
const testAsync = () => {
? try {
? ? const t = await f();
? ? console.log(t);
? } catch (err) {
? ? console.log(err);
? }
};
testAsync();
可以看到,可以使用同步的方式來處理error,但是如果判斷很多,多個(gè)異步又會(huì)導(dǎo)致到處都是判斷和try catch.因此國(guó)外的大神Dima Grossman給出了一個(gè)解決方案.直接貼官方的傳送門!
https://github.com/scopsy/await-to-js
?下面這個(gè)鏈接是一位大佬對(duì)await to js 使用中的改進(jìn).很值得一看,對(duì)優(yōu)化自己的代碼和流程很又幫助.
https://segmentfault.com/a/1190000011802045
好咯,又要去搬磚了..