在我的代码中使用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 ??
答案 0 :(得分:13)
是的,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 foo
是Promise.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返回方法返回普通值,让它们一致地行动。
总的来说 - 是的。例外情况适用于YMMV。