Javascript 如何正确捕捉承诺中的错误?
我的印象是,这两件事并不等同:Javascript 如何正确捕捉承诺中的错误?,javascript,node.js,promise,Javascript,Node.js,Promise,我的印象是,这两件事并不等同: return somePromise() .then() .then() .then() .catch(function(e) { throw e; }); 及 第一个代码段将只捕获最新版本的错误(其他错误将丢失),而第二个代码段将捕获链中任何位置的错误 但我肯定遗漏了一些东西,因为强迫用户记住在每个承诺之后都放一个陷阱,这违背了承诺的目的 我是否误解并将.catch()放在最后一个将捕获链中的任何错误?在第一种情况下,如果任何然后处理程序抛出错
return somePromise()
.then()
.then()
.then()
.catch(function(e) { throw e; });
及
第一个代码段将只捕获最新版本的错误(其他错误将丢失),而第二个代码段将捕获链中任何位置的错误
但我肯定遗漏了一些东西,因为强迫用户记住在每个承诺之后都放一个陷阱,这违背了承诺的目的
我是否误解并将
.catch()
放在最后一个将捕获链中的任何错误?在第一种情况下,如果任何然后处理程序抛出错误,那么该错误将在最后一个catch
处理程序中捕获
在第二种情况下,如果任何then
处理程序抛出错误,该错误将转到最近的catch
处理程序。当您在catch
处理程序中抛出错误时,它只会转到下一个最近的catch
处理程序
我是否有误解,将.catch()放在最后会捕获链中的任何错误
不,在大多数情况下,在承诺链末尾的捕获是正确的。但是,如果您不想因为中间失败而使整个承诺链失败,那么您可以返回值以供catch
处理程序中的下一个然后处理程序使用。一些示例可以更好地理解承诺错误。
您必须运行代码段并将结果与代码进行比较,以了解发生了什么
在此示例中,我们有:
- 4个测试,其中我们有一个抛出错误的承诺链
- 处理错误的4种方法
此示例尝试显示处理错误的4种不同方法以及结果
我希望这能帮助别人
/*
*这部分只是实用功能
*我才不管呢
*/
var el=$(“#dbg”);
变量fn={
日志:函数(val){
el.追加(“”+val+“”);
返回val;
},
错误:函数(val,强制){
var errNumber=强制?val:404;
log('引发错误:'+errNumber+'');
投掷次数;
},
正常:功能(val){
fn.log('received:'+val+'| returning:'+(val+1)+'');
返回val+1;
},
ko:功能(val){
fn.log('received:'+val+'| returning:'+(val-1)+'');
返回val-1;
},
捕获:函数(val){
log('FROM CATCH:\treceived:'+val+';returning:'+val+'');
返回val;
},
sep:功能(val){
fn.log(“”);
返回val;
},
};
log('Each fn.ok increment+1=>fn.ok(5):在绿线中记录5并返回6');
fn.ok(5);
fn.log(“”);
fn.log('每个fn.ko减量-1=>fn.ko(5):在红线中记录5并返回4';
fn.ko(5);
/*
*
*每个fn.ok增量+1
*每个fn.ko减量-1
*
*/
/*
*测试1:
*
*最后只有一个接球
*
*/
var p=Promise.resolve()
.然后(函数(){
var=1;
fn.sep();
fn.log('开始测试:'+val);
fn.log('\n\t末尾只有一个catch\n
');
日志('Promise.resolve(1)\n\t.then(fn.ok)\n\t.then(fn.ok)\n\t.then(fn.err)\n\t.then(fn.ok)\n\t.then(fn.ok)\n\t.then(fn.ok)\n\t.catch(fn.catch)';
返回val;
})
.然后(fn.ok)
.然后(fn.ok)
.然后(fn.ok)
.然后(fn.err)
.然后(fn.ok)
.然后(fn.ok)
.然后(fn.ok)
.捕获(fn.捕获)
;
/*
*测试2:
*
*与测试1相同
*最后只有一个接球
*但我们从一个错误开始
*
*/
p=p.then(函数(){
var=2;
fn.sep();
fn.log('开始测试:'+val);
fn.log('\n\t称为测试1\n\t末尾只有一个捕获\n\t但我们从一个错误\n
开始);
日志('Promise.resolve()\n\t.then(fn.err)\n\t.then(fn.ok)\n\t.then(fn.ok)\n\t.then(fn.err)\n\t.then(fn.ok)\n\t.then(fn.ok)\n\t.then(fn.ok)\n\t.catch(fn.catch);
返回fn.err();
})
.然后(fn.ok)
.然后(fn.ok)
.然后(fn.ok)
.然后(fn.err)
.然后(fn.ok)
.然后(fn.ok)
.然后(fn.ok)
.捕获(fn.捕获)
;
/*
*测试3:
*
*与测试2相同
*我们从一个错误开始
*但每一个都被锁链锁住了
*给捕手
*
*/
p=p.then(函数(){
var=3;
fn.sep();
fn.log('开始测试:'+val);
fn.log('\n\t以一个错误\n\t开始,称为测试2\n\t,但每一个都链接到\n\t一个catcher\n
');
日志('Promise.resolve('+val+')\n\t.then(fn.err)\n\t.then(fn.ok).catch(fn.catch)\n\t.then(fn.ok).catch(fn.catch)\n\t.then(fn.err)\n\t.then(fn.ok).catch(fn.catch)\n\t.then(fn.ok);
返回fn.err(val,true);
})
.然后(fn.ok).接住(fn.catch)
.然后(fn.ok).接住(fn.catch)
.然后(fn.ok).接住(fn.catch)
.然后(fn.err)
.然后(fn.ok).接住(fn.catch)
.然后(fn.ok).接住(fn.catch)
.然后(fn.ok).接住(fn.catch)
.捕获(fn.捕获)
;
/*
*测试4:
*
*与测试2相同
*我们从一个错误开始
*但每个人都有
*被拒绝的处理者
*
*/
p=p.then(函数(){
var=4;
fn.sep();
fn.log('开始测试:'+val);
fn.log('\n\t称为测试2\n\t,由错误\n\t启动,但每个\n\t都有被拒绝的处理程序\n
');
fn.log('Promise.resolve('+val+')\n\t.then(fn.err)\n\t.then(fn.ok,fn.ko)\n\t.then(fn.ok,fn.ko)\n\t.then(fn.err,fn.ko)\n\t.then(fn.ok,fn.ko)\n\t.then(fn.ok,fn.ko)\n\t.then(fn.ok,fn.ko)\n\t(fn.catch,fn.catch);
返回fn.err(val,true);
})
.然后(fn.ok,fn.ko)
.然后(fn.ok,fn.ko)
.然后(fn.ok,fn.ko)
.然后(fn.err,fn.ko)
.然后(fn.ok,fn.ko)
.然后(fn.ok,fn.ko)
.然后(fn.ok,fn.ko)
.捕获(fn.捕获)
;代码>
.line{
边框:实心1px透明;
保证金:3倍;
填充:3倍;
}
.行,好的,
.line.ko,
.电话线{
左边距:24px;
左:3倍;
}
o
return somePromise()
.catch(function(e) { throw e; });
.then()
.catch(function(e) { throw e; });
.then()
.catch(function(e) { throw e; });
.then()
.catch(function(e) { throw e; });
return somePromise()
.then()
.then()
.then()
.catch(function(e) { throw e; });
try {
var val = someFunction();
val = fn(val); // p.then(x => ...);
//...
return val;
} catch (e) {
throw e; // this catch didn't actually do anything, but will be reached if someFunction
// throws an error during execution
}
return somePromise()
.catch(function(e) { throw e; });
.then()
.catch(function(e) { throw e; });
.then()
.catch(function(e) { throw e; });
.then()
.catch(function(e) { throw e; });
try {
try {
var val = someFunction();
return val;
} catch (e) {
throw e;
}
val = fn(val); // this is a then(); If it's really an empty then - a noop
} catch (e) {
throw e;
}
val = fn(val); // this is a then(); If it's really an empty then - a noop
} catch (e) {
throw e;
}
val = fn(val); // this is a then(); If it's really an empty then - a noop
} catch (e) {
throw e; // yep, even this last one will be reached
}
}