JavaScript Promise中的then和finally有什么区别?

表面上看,Promise.prototype.then()Promise.prototype.finally()非常相似。但是你需要记住一些重要的区别。

首先,最明显的区别是finally()不会接收到promise链的结果值。同样,由于finally()不接收值,因此无法更改promise的解析值。

new Promise((resolve, reject) => resolve(10))
  .then(x => {
    console.log(x); // 10
    return x + 1;
  })
  .finally(x => {
    console.log(x); // undefined
    return x + 2;
  });
// Promise解析为11,即then()的返回值

另一个区别与错误处理和promise链的解析方式有关。有时,你可能希望推迟捕获promise链中的错误,以便在其他地方处理它们。在这种情况下,链接的then()将不会被执行,而finally()会执行。此外,如果前面的catch()抛出错误,你将面临相同的情况。

new Promise((resolve, reject) => reject(0))
  .catch(x => {
    console.log(x); // 0
    throw x;
  })
  .then(x => {
    console.log(x); // 不会执行
  })
  .finally(() => {
    console.log('清理工作'); // '清理工作'
  });
// Uncaught (in promise) 0

重要的是,除非有非常特定的原因,否则不应该将then()finally()互换使用。作为一个经验法则,finally()应该用于清理工作(清除定时器、清空引用、重置UI状态等)。