web-dev-qa-db-ja.com

なぜPromiseとcatchコールバックの両方が呼び出されるのですか?

次のコードを実行すると、「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')});

誰かが説明できますかなぜ成功が記録されるのですか?

15
c 2

thenコールバックは後ではなく前にあるため、catchコールバックが呼び出されます。拒否はcatchによってすでに処理されています。順序を変更すると(つまり(promise.then(...).catch(...)))、thenコールバックは実行されません。

[〜#〜] mdn [〜#〜] は、.catch()メソッドが「コールバックの戻り値に解決する新しいpromiseを返す」ことを示しています。 catchコールバックは何も返さないため、promiseはundefined値で解決されます。

12

成功が記録される理由を誰かが説明できますか?

つまり、Promiseチェーン内の_.then_に続く_.catch_は常に実行されます(それ自体にエラーが含まれている場合を除く)。

理論的な説明

あなたのコードは実際にはPromiseチェーンであり、最初に実行されます同期的に完全に設定されますその後、非同期に。 JavaScriptエンジンは、reject()またはErrorを、rejectコールバックを含むチェーンの最初の_.then_に渡します。拒否コールバックは、_.then_に渡される2番目の関数です。

_.then(
function (){
    //handle success
},
function () {
    //handle reject() and Error
})
_

_.catch_の使用は、次の場合の単なる構文シュガーです。

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

_.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();
_

実行時にコンソールに次の出力が表示されます。

_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
_
9
rabbitco

約束の解決に成功し、.then> .catchですが、thencatchの両方がまだ呼び出されていましたthenに、目に見えないエラーが発生するバグがあったためかもしれませんcatchで明示的にエラーをコンソールしない限り。これは、厳密モードでもPromiseがエラーを吸収するのに苦労することの1つです。

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);
});
0
bit-less