蓝鸟承诺中的简单语句是否应该被 Promise.try 包围?

Should simple statement be surrounded by Promise.try in bluebird promises?

使用 promisified 请求模块,我想获取响应的 body 属性。不确定我是否应该使用 Promise 尝试。

那么哪一个是正确的?

A. 无 Promise.try

request.getAsync("http://example.com")
       .then( x => x.body )
       .tap( x=> console.log('body:',x) )

B.和Promise.try

request.getAsync("http://example.com")
       .then( x => Promise.try( () => x.body ) )
       .tap( x=> console.log('body:',x) )

definition of this Promise.try是:

Start the chain of promises with Promise.try. Any synchronous exceptions will be turned into rejections on the returned promise.

所以这取决于request.getAsync方法的实现。它会抛出任何异常吗?

如果答案是"no",则不需要使用Promise.try

如果答案是 "yes",如果您需要捕获 request.getAsync 抛出的错误作为被拒绝的承诺,您 可以 使用 Promise.try .在这种情况下,您可以将 request.getAsync 里面 Promise.try:

Promise.try(() => {
    return request.getAsync("http://example.com");
}).tap(x => console.log('body:', x.nody));

请注意,如果答案是 "yes" 但不想将异常捕获为被拒绝的承诺,则不需要使用 Promise.try.

在 promise 链的第一个元素之后,错误保证会抛出链的错误路径,并可以被 .then(null, errorHandler).catch(errorHandler).

捕获

因此,除了可靠地启动链之外,使用 Bluebird 的 Promise.try() 毫无意义。这样做只会增加代码量并降低效率。

内链怎么样?

这个比较有意思。内部链通常用于允许通过闭包访问早期结果。扁平锁链失去此能力。

考虑:

request.getAsync("http://example.com")
.then( x => {
    return untrusted.method().then((y) => other.method(x, y));
});

内链有自己的启动器,untrusted.method(),这可能会导致两种方式之一的失败:

  • 它可能会抛出。
  • 它可能 return 不那么可行。

抛出是不可避免的(不解决untrusted.method()),尽管抛出的错误可以在外链中捕获。

但是一个非thenable是可以防的。你可以这样写:

request.getAsync("http://example.com")
.then(x => {
    return Promise.try(untrusted.method).then((y) => other.method(x, y) );
});

现在Promise.try()确保内链有一个可靠的启动。 Promise.try(untrusted.method) 保证可用。

作为奖励,由 untrusted.method() 抛出的错误现在可以在外链 或内链 中捕获,这很有用,特别是对于错误恢复。

Promise.resolve(untrusted.method()) 将类似地防止非 thenable 被 returned 但不允许在内链中捕获同步抛出。

所以总而言之,

  • 在承诺链中,在 Promise.try() 中包装同步表达式没有任何价值。
  • 在 promise 链中,包装 trustedPromise.try().
  • 中的异步 function/method 调用没有任何价值
  • 在承诺链中,将不受信任的 function/method 调用包装在 Promise.try() 中以保证内部链的可靠启动具有潜在的巨大价值。

Not sure if I should use a Promise.try.

,你不应该。在 promise then 回调中,所有同步异常都将被捕获并导致结果 promise 被拒绝,您无需为此做任何事情。没有 try/catch 语句,没有 Promise.try 调用。它们只是不必要的绒毛。

Promise.try 只应在 promise 链的开头使用,此时您尚未处于 promise 回调中。