bluebird promise.method包装函数返回一个promise,是吗?

时间:2015-03-22 13:36:46

标签: promise bluebird

在我的代码中使用bluebird,我使用promise.method来覆盖原始函数,就像api说的那样。然后我编写一个返回promise的函数,并使用promise.method来覆盖它。这两个函数返回同样的:

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来覆盖函数返回一个promise ??

1 个答案:

答案 0 :(得分:13)

构建有错误的异步API

是的,Promise.method的目的是让方法安全 - 例如,如果你有一个类似的方法:

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

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

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

Promise.method做什么

Promise.method基本上用try / catch包装你的方法,并将抛出的错误转换为拒绝并将值返回到履行中。如果您的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非常有用。

它还有一个额外的好处,就是让你从promise返回方法返回普通值,让它们一致地行动。

那么我应该用它来包装返回promises的函数吗?

总的来说 - 是的。例外情况适用于YMMV。