在这种情况下,您可以主要使用其中任何一种(只有一个行为差异)。第一个是标准的 Promise 功能,可以与任何 Promise 库一起使用。
Promise.try() 是 Bluebird 库专门实现的功能,不属于我所知道的任何标准流程的一部分。
使用Promise.try() 的原因是如果您有一个返回承诺的函数,但生成该承诺的代码也可能导致同步异常。由于该异常不在任何承诺处理程序中,因此您将混合使用错误处理。一些代码执行路径可能会导致返回一个将解析或拒绝的承诺,而其他代码执行路径可能会引发异常。为了安全地编写代码,你必须同时响应 promise 并在代码周围放置一个 try/catch 块,这会变得笨拙。
Promise.try() 只是一种自动捕获任何异常并将其转换为拒绝的方法(类似于.then() 处理程序中发生的情况)。
在您的两种情况下,Promise.try() 不会以这种方式使您受益,因为new Promise() 回调已经捕获异常并将它们转换为拒绝,因此那里已经为您完成了功能。你可以在这里看到演示:http://jsfiddle.net/jfriend00/wLov9844/
Bluebird 文档提供了这个例子,更清楚地显示了好处:
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() 将始终返回一个promise,即使该方法内部的代码同步抛出异常。这简化了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() 也会自动返回已解决的承诺。由于通过您的第一个示例的一条路径没有解决或拒绝,这将导致您的两个示例有所不同。