为什么 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
这样的链排序但仍然同时调用了 then
和 catch
的人,这可能是因为您的 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
中处理异常
我有以下代码,当它被执行时,它 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
这样的链排序但仍然同时调用了 then
和 catch
的人,这可能是因为您的 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
中处理异常