finally 什么时候在 js Promise 上下文中被调用?

When does the finally gets called in the js Promise context?

finally 何时在 js Promise 上下文中被调用?

我一开始以为finally会在最后一个then之后被调用。但后来我明白了,确定最后一个then是不可能的。我下面的尝试也证明了:

function f(resolve, reject) {
    resolve("foo");
};
var p = new Promise(f);
p.then(function(data) {
     console.log("data: " + data); 
});
p.finally(function(data) {
     console.log("in finally");
});
p.then(function(data) {
     console.log("data: " + data); 
});

输出:

data: foo
in finally
data: foo

因此,finally 不会在最后一个 then 之后调用。我认为 finally 应该在 resolve 之后调用。但在我上面尝试的示例代码中,我们可以看到情况并非如此(因为在 resolvefinally 之间调用了已注册的 then)。

因此,我很困惑,无法理解什么时候会调用finally

None 的 Promise 是链接在一起的 - 一切都直接连接到根 p Promise。因此,当 p Promise 解析(或拒绝)时,所有 .then.finally 回调附加到该 Promise 运行,可能按照它们附加的顺序。

在大多数情况下,Promise 将被链接起来 - (例如 .then(() ... ).then.then(() ... ).finally)。然后,finally 将在前一个 .then 完成后 运行, 在前一个 .then 抛出:

function f(resolve, reject) {
    resolve("foo");
};
var p = new Promise(f);
p.then(function(data) {
     console.log("data: " + data); 
})
.finally(function(data) {
     console.log("in finally");
});

function f(resolve, reject) {
    resolve("foo");
};
var p = new Promise(f);
p.then(function(data) {
     console.log("data: " + data);
     console.log("About to throw");
     throw new Error();
})
.finally(function(data) { // Above Promise throws, so if this was a .then, it wouldn't run
     console.log("in finally");
});
// No .catch, so this results in an unhandled Promise rejection

在决定何时执行时,.finally 不会提前查看是否有任何链接 - 相反,.finally 回调会在 Promise 被调用时立即执行解决或拒绝。

.finally 补充 thencatchthen 块在实现时调用,catch 在拒绝时调用,finally在这两种情况下都被调用(例如:您进行 API 调用,在 then 块中处理数据,在 catch 块中显示错误消息,在 finally 块中你隐藏加载微调器)。

然后链继续。

Promise.reject('execute some action')
  .then(() => console.log('I\'ll handle success here'))
  .catch(() => console.log('error handling'))
  .finally(() => console.log('this block will be executed either way'))
  .then(() => console.log('and the adventure continues'))