Promise.try
和Promise.method
)?这似乎是因为(除其他事项外)错误处理对于两者来说是不同的(同步是用try
/ catch
捕获的,而async是用.catch
捕获的。
但不要then
语句接受同步功能(throws
被视为拒绝,return
视为已解决)或承诺(使用标准reject
/ { {1}})在一系列链式函数的第一个方法之后的任何一个? (例如,在a()。然后(b).then(c).catch(function(e){}) - b / c部分)。最终resolve
似乎从promise中的拒绝或同步代码中的throw中收集错误。
这些额外的Bluebird函数的主要目的仅在于回调链的第一部分吗?或者是否有其他原因将同步代码转换为承诺。
答案 0 :(得分:0)
让我们看一个非常基本的例子,我们在某段代码中有异步和同步路径:
var expiryTime = 1457155658238;
var cachedCopy = 'abcdefghijk';
var p = Date.now() > expiryDate ? getNewCopy() : cachedCopy;
p.then(function (information) {
// do something
});
请注意这里的问题?由于cachedCopy
不是承诺,如果条件沿着此路径行进,则会抛出错误。因此,我们需要将cachedCopy
包装成一个承诺:
var p = Date.now() > expiryDate ? getNewCopy() : Promise.resolve(cachedCopy);
但是,如果我们必须为多个代码路径执行此操作,这可能会变得乏味。您可能想知道为什么我们不要简单地将它放入函数中,然后在返回值上调用Promise.resolve
以将其包装到promise中。拿这个代码:
var expiryTime = 1457155658238;
var cachedCopy = 'abcdefghijk';
var canGetNewCopy = false;
function getInfo() {
if (Date.now() < expiryDate) return cachedCopy;
if (canGetNewCopy) return getNewCopy();
throw new Error('fail!');
}
Promise.resolve(getInfo()).then(function (information) {
// do something
}).catch(function (error) {
console.log('an error occured!');
cleanup();
});
如果超过到期日会怎样?因为getInfo()
会抛出错误,所以清理代码不会运行。
Bluebird的Promise.try
解决了所有这些问题。通过捕获传递的函数内部抛出的错误,以及在同步返回的情况下将值包装到promise中,这可以节省大量代码包装并减少代码中细微错误的可能性。现在我们的示例看起来像这样:
var expiryTime = 1457155658238;
var cachedCopy = 'abcdefghijk';
var canGetNewCopy = false;
Promise.try(function () {
if (Date.now() < expiryDate) return cachedCopy;
if (canGetNewCopy) return getNewCopy();
throw new Error('fail!');
}).then(function (information) {
// do something
}).catch(function (error) {
console.log('an error occured!');
cleanup();
});
现在如果在Promise.try
回调中抛出错误,则返回的promise将被拒绝,因此清理代码将运行。出于类似的原因,Bluebird中也存在Promise.method
(以确保API中的函数始终返回承诺)。