为什么 Promise 的 then & catch 回调都会被调用?

Why do both Promise's then & catch callbacks get called?

我有以下代码,当它被执行时,它 returns “rejected”和“success”:

// javascript promise
var promise = new Promise(function(resolve, reject){
  setTimeout(function(){reject()}, 1000)
});
promise
  .catch(function(){console.log('rejected')})
  .then(function(){console.log('success')});

谁能解释一下为什么记录成功?

调用 then 回调是因为 catch 回调在它之前,而不是之后。 catch 已处理拒绝。如果您更改顺序(即 (promise.then(...).catch(...))),则不会执行 then 回调。

MDN 表示 .catch() 方法 "returns a new promise resolving to the return value of the callback"。你的 catch 回调没有 return 任何东西,所以承诺是用 undefined 值解决的。

Could anyone explain why success is logged?

简而言之:Promise 链中 .catch 之后的 .then 将始终执行(除非它本身包含错误)。

理论解释

您的代码实际上只是一个 Promise 链,它首先被 同步 设置为在之后 异步 完成。 Javascript 引擎会将任何 reject()Error 传递给链下的第一个 .then,其中包含 reject 回调。拒绝回调是传递给 .then:

的第二个函数
.then(
function (){
    //handle success
},
function () {
    //handle reject() and Error
})

.catch 的使用只是语法糖:

.then(null, function () {
    //handle reject() or Error
})

每个 .then 自动 returns 一个新的 Promise 可以由后续的 .then(或 .catch' s 也是 .then 的)。

可视化承诺链的流程

您可以通过以下示例可视化代码流:

var step1 = new Promise (function (resolve, reject) {

  setTimeout(reject('error in step1'), 1000);
})

var step2 = step1.then(null, function () {

  // do some error handling
  return 'done handling errors'
})

var step3 = step2.then(function () {

  // do some other stuff after error handling
  return 'done doing other stuff'
}, null)

setTimeout (function () {

console.log ('step1: ', step1);
console.log ('step2: ', step2);
console.log ('step3: ', step3);

console.log();
console.log ('Asynchronous code completed')
console.log();
}, 2000);

console.log ('step1: ', step1);
console.log ('step2: ', step2);
console.log ('step3: ', step3);

console.log();
console.log ('Synchronous code completed')
console.log();

这将在运行时在控制台中产生以下输出:

step1:  Promise { <rejected> 'error in step1' }
step2:  Promise { <pending> }
step3:  Promise { <pending> }

Synchronous code completed

step1:  Promise { <rejected> 'error in step1' }
step2:  Promise { 'done handling errors' }
step3:  Promise { 'done doing other stuff' }

Asynchronous code completed

对于那些成功解决了 promise 和像 .then > .catch 这样的链排序但仍然同时调用了 thencatch 的人,这可能是因为您的 then 有一个您无法看到的错误抛出错误,除非您在 catch 中明确地控制错误。即使在严格模式下,Promises 也会吸收错误,这是我最讨厌的事情之一。

const promise = new Promise(resolve => resolve())
.then(() => {
    console.log('then');
    not.defined = 'This causes the catch to fire even though the original promise resolved successfully.';
})
.catch((e) => {
    console.log('catch');
    // console.error(e);
});

对我来说 catch() 是在成功承诺后被调用的,并且 .then() 中没有错误。

原因是,我听取了一个随成功承诺而变化的值,以及 运行 一个方法。

此方法抛出静默错误,因为它被计为承诺的一部分。

与@Timar 类似,对我来说,调用 catch 的原因是“then”包含异常代码。所以正常执行"then"后,到达异常代码时,在"catch"xD

中处理异常