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

c 2*_*c 2 13 javascript ecmascript-6 es6-promise

我有以下代码,当它执行时,它返回" 被拒绝 "和" 成功 ":

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

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

Mic*_*ski 12

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

MDN表示该.catch()方法"返回一个解决回调返回值的新承诺".你的catch回调函数不会返回任何内容,所以承诺会以undefined值来解决.


rab*_*tco 10

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

简而言之:.then跟随.catch在一个Promise链就一定会执行(除非它本身含有错误).

理论解释

您的代码实际上只是一个Promise首先同步执行的链,然后将其设置为异步完成.Javascript引擎将在其中传递任何reject()Error第一个.then链接,并reject在其中进行回调.拒绝回调是传递给.then:的第二个函数:

.then(
function (){
    //handle success
},
function () {
    //handle reject() and Error
})
Run Code Online (Sandbox Code Playgroud)

使用.catch只是语法上的:

.then(null, function () {
    //handle reject() or Error
})
Run Code Online (Sandbox Code Playgroud)

每个人.then自动返回一个新的Promise,可以被后续.then的(或者.catch也是.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();
Run Code Online (Sandbox Code Playgroud)

在运行时将导致控制台中的以下输出:

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
Run Code Online (Sandbox Code Playgroud)


bit*_*ess 6

.then对于那些拥有成功解决的 Promise 和像>这样排序的链.catch,但仍然同时拥有 yourthencatchCalled 的人,可能是因为你then有一个抛出错误的错误,除非你在catch. 这是我最讨厌的事情之一,即使在严格模式下,Promise 也会吸收错误。

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);
});
Run Code Online (Sandbox Code Playgroud)