我什么时候应该使用哪个?以下是相同的吗?
新的Promise()示例:
function multiRejectExample(){
return new Promise(function (resolve, reject){
if(statement){
console.log('statement 1');
reject(throw new Error('error'));
}
if(statement){
console.log('statement 2');
reject(throw new Error('error'));
}
});
}
Promise.try()示例:
function tryExample(){
return Promise.try(function(){
if(statement){
console.log('statement 1');
throw new Error('error');
}
if(statement){
console.log('statement 2');
throw new Error('error');
}
});
}
答案 0 :(得分:8)
在这种情况下,你可以主要使用(有一个行为差异)。第一个是标准承诺功能,可以与任何promise库一起使用。
Promise.try()
是Bluebird图书馆专门实现的功能,不属于我所知道的任何标准流程。
使用Promise.try()
的原因是,如果您有一个返回promise的函数,但生成该promise的代码也可能导致同步异常。由于该异常不在任何promise处理程序中,因此您可以混合使用错误处理。某些代码执行路径可能会导致返回将要解析或拒绝的promise,而其他代码执行路径可能会引发异常。要安全地编写代码,你必须同时响应promise并在代码中放置一个try / catch块,这些代码变得难以处理。
Promise.try()
只是一种自动捕获任何异常并将其变为拒绝的方法(类似于.then()
处理程序中发生的情况)。
在您的两种情况下,Promise.try()
不会以这种方式使您受益,因为new Promise()
回调已经捕获异常并将其变为拒绝,因此在那里已经为您完成了功能。你可以在这里看到:http://jsfiddle.net/jfriend00/wLov9844/
Bluebird doc提供了这个示例,它更清楚地显示了这个好处:
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()
也会自动返回已解决的承诺。由于您的第一个示例中的一条路径无法解析或拒绝,因此这会导致您的两个示例产生差异。
答案 1 :(得分:3)
他们不一样。
考虑两个陈述都是假的情况。在这种情况下,multiRejectExample()
永远不会拒绝或来解决已退回的承诺,而tryExample()
将会"通过"并自动解决承诺(价值为undefined
,因为您不会返回任何内容)。
演示:
var Promise = require('bluebird');
function test1() {
return Promise.try(function() { });
}
function test2() {
return new Promise(function(resolve, reject) { });
}
test1().then(function() { console.log('resolved #1'); });
test2().then(function() { console.log('resolved #2'); });
这将记录resolved #1
但不记录resolved #2
,因为承诺永远不会被解决(也不会被拒绝)。
答案 2 :(得分:3)
以下是否相同?
没有。正如@robertklep已经提到的,当statement
为假时,它们会有不同的结果。 Promise.try
捕获异常,否则使用函数的返回值进行解析,而Promise
构造函数只是创建一个新的promise,而不关心它是什么时候resolve()
d。
我什么时候应该使用哪个?
您应该使用Promise
构造函数iff,而仅在时使用promisifying an asynchronous callback API。其他一切,特别是when involving other promises,基本上都是反模式
所以不要像你在问题中那样使用它。
您通常也不会throw
。您正在编写一个返回promise的函数(因为它是异步的),它应该总是返回一个promise。如果要返回因错误而被拒绝的承诺,您可以使用Promise.reject
显式创建一个承诺。因此,正确的方法是
function multiRejectExample(){
if (statement){
console.log('statement 1');
return Promise.reject(new Error('error'));
}
if (statement){
console.log('statement 2');
return Promise.reject(new Error('error'));
}
return Promise.resolve();
}
当然,这个特定的例子没有多大意义,因为你的情况都不是异步的,根本就没有理由使用promises。只需使用抛出异常的同步函数。通常,您最终会有一些return …
实际上是异步承诺,而不是undefined
实现的承诺。
现在,如果你有这样的功能,并且厌倦了反复写return Promise.reject
,你可以使用Bluebird特定的Promise.try
和Promise.method
方法作为语法糖< / em>的