Jas*_*n C 12 javascript node.js promise bluebird
我看到Bluebird的文档,finally但我仍然不太了解与之相比的差异then.
要清楚:我确切地知道为什么then在a之后调用catch.我希望在捕获之后调用它.这是意图.我的问题是:如果我希望代码总是被执行而不管承诺状态,那么thenvs 之间的区别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);
Run Code Online (Sandbox Code Playgroud)
这测试了四种情况:
.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
Run Code Online (Sandbox Code Playgroud)
现在,我问的原因是因为我看到了对我提出的另一个问题的评论:
不确定你的承诺是否支持它,但你应该改变最后一个
.then,.finally以便busy始终清除.
从我非常有限的知识then和上面的测试来看,似乎then已经足够了.但在那次评论之后,我正在质疑自己以及使用then执行"最终"代码的安全性.
所以我的问题是:then和之间有什么区别finally?他们看起来行为相同,但什么时候需要使用finally而不是then?
Tho*_*mas 14
第一个区别:有时你不想在它们出现的地方捕获错误,但在使用这个函数的代码中,所以你不会捕获它们.在这种情况下,你不能替代then()和finally().
有时你必须清理一些事情是否有错误(归零引用,清除超时......这样的东西).这就是你使用的地方finally().
第二个区别:你传递给的函数也catch()可能抛出,然后你会有一个被拒绝的Promise,并且then()不会调用以下内容.
(所以最后一个catch仍然会在错误上执行,不知道那个)
是的,这就是重点finally().它将在任何情况下执行而不更改已解析的值.
您可能想要阅读/谷歌一点try {} finally {},没有捕获.
.then并且.finally不一样。
.then是主要的承诺原语。这是Promises/A+ 规范中彻底定义的内容,所有 Promise 库都将实现它。
Bluebird.finally处理程序将“无论承诺的命运如何都会被调用”。因此,未处理的异常仍会触发.finally.
new Promise((resolve, reject) => reject(false))
.finally(a => console.log('finally', a))
// finally undefined
// Unhandled rejection false
new Promise((resolve, reject) => reject(false))
.then(a => console.log('then', a))
// Unhandled rejection false
Run Code Online (Sandbox Code Playgroud)
.finally 不会改变承诺的已解析值,也不会收到承诺链的结果。
new Promise((resolve, reject) => reject(false))
.catch(e => {
console.log(e)
return 2
})
.finally(a => {
console.log('finally', a)
return 1
})
.then(res => console.log('res', res))
// finally undefined
// res 2
Run Code Online (Sandbox Code Playgroud)
这些方法在您的测试用例中看起来相似,因为测试会捕获所有错误,并且您仅使用 Promise 进行流控制,而不依赖于沿着 Promise 链解决/拒绝的值。
好吧,经过 KevinB 的一些聊天和大量帮助后,我发现了至少一个不同之处。考虑以下两个新测试:
function test5 () {
console.log("REJECT + THEN + CATCH/THROW + THEN");
return new Promise((resolve, reject) => reject(new Error("rejected")))
.then(() => console.log("then"))
.catch(function(err) { throw new Error("error in catch"); })
.then(() => console.log("end"));
}
function test6 () {
console.log("REJECT + THEN + CATCH/THROW + FINALLY");
return new Promise((resolve, reject) => reject(new Error("rejected")))
.then(() => console.log("then"))
.catch(function(err) { throw new Error("error in catch"); })
.finally(() => console.log("end"));
}
Run Code Online (Sandbox Code Playgroud)
在这些中,承诺被拒绝,但从中抛出错误 catch.
在这两种情况下,promise 最终都被拒绝了,但对于仍然执行的finally情况finally,then则不是。
所以这就是区别。它们几乎相同,唯一的例外是当catch处理程序抛出错误时,finally执行和then不执行。
这意味着我引用的评论也有优点:如果在我的错误处理程序中发生另一个错误,athen不能保证清理,但 afinally会。这就是我失踪的情况。
| 归档时间: |
|
| 查看次数: |
22214 次 |
| 最近记录: |