bluebird promise.method 包装函数 return 一个承诺,可以吗?

bluebird promise.method to wraps a function return a promise,is that ok?

在我的代码中使用 bluebird,并且我使用 promise.method 来覆盖原始函数,就像 api say.Then 我写了一个 return 承诺的函数,并使用 promise.method 覆盖 it.Those 两个函数 return 相同:

function () {
    var ret = new Promise(INTERNAL);
    ret._captureStackTrace();
    ret._pushContext();
    var value = tryCatch(fn).apply(this, arguments);
    ret._popContext();
    ret._resolveFromSyncValue(value);
    return ret;
}

可以用promise.method覆盖函数return一个promise吗?

构建异步 APIs 有错误

是的,Promise.method 的目的是让方法安全地抛出 - 例如,如果你有一个看起来像这样的方法:

function foo(jsonStr){
    var obj = JSON.parse(jsonStr);
    return getApi(obj.endpoint);
}

如果传递一个无效的对象,它可能 throw 出错 - 所以如果你传递一个无效的字符串,它会抛出(而不是拒绝)。这意味着您必须防范代码中抛出的错误和拒绝的承诺,并在代码中添加 } catch(e){ .catch(function(e){

这种形式的编程创建了一个弱而脆弱的 API 来区分同步和异步错误,并且可能(并且将会)根据错误发生的时间创建竞争条件。 如果函数 可能 异步执行某些操作,它 必须始终 异步执行 。这是 a core concept 开发异步 APIs - 否则你最终会遇到竞争条件和其他问题。

Promise.method 的作用

Promise.method 基本上用 try/catch 包装您的方法,并将抛出的错误转换为拒绝,将 returned 值转换为实现。如果你的 function fooPromise.method 它会 总是 拒绝错误而不是抛出。这解决了竞争条件问题,因为您的方法现在总是以相同的方式失败。

var foo = Promise.method(function(jsonStr){
    var obj = JSON.parse(jsonStr); // if this throws - you get a rejection
    return getApi(obj.endpoint);
});

什么时候不使用它

有些情况下您可以不使用 Promise.method - 例如,当您的方法主体位于承诺链中或者您 100% 确定它不会抛出时。总的来说 - 我发现 Promise.method 很有用。

它还有一个额外的好处,就是让您 return 来自 promise returning 方法的普通值,并让它们始终如一地运行。

那么我应该包装 return 承诺的函数吗?

总的来说 - 是的。例外情况和 YMMV。