您可以用得最多无论是在这种情况下(有一个行为差)。第一个是标准的承诺功能,可以与任何承诺库一起工作。
Promise.try()
是由Bluebird库专门实现的功能,不属于任何我知道的标准过程。
使用Promise.try()
的原因是,如果您有一个函数返回承诺,但生成该承诺的代码也可能会导致同步异常。由于该异常不在任何承诺处理程序中,因此您可能会混合使用错误处理。某些代码执行路径可能会导致返回的承诺被解析或拒绝,而其他代码执行路径可能会引发异常。为了安全地进行编码,你必须同时响应这个承诺,并在代码中放置一个try/catch块,这个代码很笨拙。
Promise.try()
只是一种自动捕捉任何异常并将它们变为拒绝的手段(类似于.then()
处理程序中发生的情况)。
在这两种情况下,Promise.try()
不会以这种方式让您受益,因为new Promise()
回调已捕获异常,并将它们变为拒绝,以便您的功能已在您那里完成。你可以在这里看到演示:http://jsfiddle.net/jfriend00/wLov9844/
蓝鸟文档提供了这个例子显示了利益更加清晰:
function getUserById(id) {
return Promise.try(function() {
if (typeof id !== "number") {
// Courtesy of Promise.try() this exception will be turned
// into a returned promise that is rejected with the
// exception as the reason
throw new Error("id must be a number");
}
return db.getUserById(id);
});
}
getUserById().then(successFn, errFn);
采用Promise.try()
这里可以确保getUserById()
总是会返回一个承诺,即使该方法内部的代码会同步引发异常。这简化了getUserById()
的使用,因为您可以始终响应承诺并且不必使用您自己的异常处理程序。
没有Promise.try()
,你可以自己编写同样的事情,像这样(赶在函数内的所有可能的同步异常):
function getUserById(id) {
try {
if (typeof id !== "number") {
throw new Error("id must be a number");
}
return db.getUserById(id);
} catch(e) {
return Promise.reject(e);
}
}
getUserById().then(successFn, errFn);
或者,你可以像这样的代码时:
function getUserById(id) {
if (typeof id !== "number") {
throw new Error("id must be a number");
}
return db.getUserById(id);
}
try {
getUserById().then(successFn, errFn);
} catch(e) {
errFn(e);
}
据推测,你可以看到Promise.try()
在某些情况下可以简化事情。
仅供参考,您的第一个例子中,使用的是无效的语法。你可以这样做:
reject(throw new Error('error'));
我假设你的意思是这样的:
reject(new Error('error'));
虽然我不认为这是真的,你在问,也Promise.try()
会是什么自动返回已解决的承诺,如果您没有自己回复承诺。由于通过第一个示例的一条路径不能解决或拒绝,因此这会导致您的两个示例有所不同。
松散相关:[Promise.reject vs throw error](http://stackoverflow.com/q/28703241/1048572)。你不应该使用'new Promise'构造函数,除非你真的在做一些异步的事情。这里的正确方法是'返回Promise.reject(...)'(或使用'Promise.try' /'Promise.method')。 – Bergi