【发布时间】:2017-04-29 01:09:53
【问题描述】:
我看到了 Bluebird 的 finally 的文档,但我仍然不太明白与 then 的区别。
明确一点:我确切地知道为什么 then 在 catch 之后被调用。我希望在捕获后调用它。这就是意图。我的问题是:如果我想要代码始终被执行而不管承诺状态如何,then 与 finally 之间有什么区别?
我构建了这个测试:
var Promise = require("bluebird");
function test1 () {
console.log("RESOLVE + THEN + CATCH + THEN");
return new Promise((resolve, reject) => resolve())
.then(() => console.log("then"))
.catch(err => console.log("error:", err.message))
.then(() => console.log("end"));
}
function test2 () {
console.log("REJECT + THEN + CATCH + THEN");
return new Promise((resolve, reject) => reject(new Error("rejected")))
.then(() => console.log("then"))
.catch(err => console.log("error:", err.message))
.then(() => console.log("end"));
}
function test3 () {
console.log("RESOLVE + THEN + CATCH + FINALLY");
return new Promise((resolve, reject) => resolve())
.then(() => console.log("then"))
.catch(err => console.log("error:", err.message))
.finally(() => console.log("end"));
}
function test4 () {
console.log("REJECT + THEN + CATCH + FINALLY");
return new Promise((resolve, reject) => reject(new Error("rejected")))
.then(() => console.log("then"))
.catch(err => console.log("error:", err.message))
.finally(() => console.log("end"));
}
// run tests "sequentially" so console output doesn't get blended
setTimeout(test1, 500);
setTimeout(test2, 1000);
setTimeout(test3, 1500);
setTimeout(test4, 2000);
这测试了四种情况:
-
.then(...).catch(...).then(...)已解决的承诺。 -
.then(...).catch(...).then(...)被拒绝的承诺。 -
.then(...).catch(...).finally(...)已解决的承诺。 -
.then(...).catch(...).finally(...)被拒绝的承诺。
我看到的结果是案例 1+2 的行为与 3+4 相同:最后一位(then 或 finally 取决于测试)无论之前发生什么都会按预期执行。该程序的输出是:
RESOLVE + THEN + CATCH + THEN
then
end
REJECT + THEN + CATCH + THEN
error: rejected
end
RESOLVE + THEN + CATCH + FINALLY
then
end
REJECT + THEN + CATCH + FINALLY
error: rejected
end
现在,我问的原因是因为我看到了comment on this other question I asked:
不确定您的承诺是否支持它,但您应该将最后一个
.then更改为.finally以便始终清除busy。
从我对then 的有限知识和上面的测试来看,似乎then 就足够了。但在那条评论之后,我开始质疑自己以及使用then 执行“finally”代码的安全性。
所以我的问题是:then 和 finally 有什么区别?它们看起来表现得一样,但我什么时候需要使用finally 而不是then?
【问题讨论】:
-
如果你总是遇到被拒绝的承诺,这意味着你只解决了承诺,那么当然没有什么区别......我错过了你的问题吗?这一切似乎都很明显..
-
适用于承诺可以被解决或被拒绝的情况。在你的情况下,它总是得到解决,所以没有区别。
-
.catch 使它成为一个已解决的承诺..
-
@JasonC, 1st:有时您不想在错误出现的地方捕获错误,而是在使用此函数的代码中;所以你不会抓住他们。在这种情况下,您不能替换
then()和finally()。有时你必须清理某事。不管有没有错误。 (清空引用清除超时,......类似的东西)这就是你使用finally()的地方。第二:你传递给catch()的函数也可以抛出,那么你会得到一个被拒绝的Promise并且不会调用下面的then()。 -
好吧,现在你不能删除它了。问题解决了!
标签: javascript node.js promise bluebird