有人可以解释一下,为什么Promise会在调用reject时触发then()函数(以及catch()函数)?
调用resolve时,只触发then() - OK
当调用reject时,调用then()和catch()函数 - 问题
static logIn(email, password) {
async function getSession () {
let data = new FormData();
data.append('email', email);
data.append('password', password);
const response = await fetch(
url,
{
method: 'POST',
mode: 'cors',
body: data,
cache: 'no-cache',
headers: {
'Accept': 'application/json',
},
}
);
const json = await response.json();
return json;
}
return new Promise((resolve, reject) => {
getSession()
.then(json => {
if (json.status === 'ok') {
resolve('OK');
} else {
reject('LogIn failed.');
}
})
.catch(error => reject('LogIn failed.'))
});
};
logIn()
.then(console.log('logged in'))
.catch(error => console.log('not logged in'));
答案 0 :(得分:4)
注意这一行:
.then(console.log('logged in'))
then
方法需要callback,但您正在调用函数并将return
值作为参数传递。如果console.log返回了一个函数,则then
将在内部调用该函数,以防止解析。但事实并非如此,因为console.log没有返回值! (它只是打印并退出)。
在javascript中,没有返回值等于undefined
。所以,你正在做的是在任何情况下调用console.log 并将undefined作为参数传递。因此,您的代码等同于:
console.log('logged in');
...
.then(undefined)
...
您的意思可能是将日志记录回调作为参数传递,并让 Promise 在解析时调用该回调:
.then(() => console.log('logged in'));
或者,为了更清楚地了解正在发生的事情,你可以通过这种方式看到它:
function log() {
console.log('logged in');
}
...
.then(log);
我们没有调用该函数,只是传递引用!
答案 1 :(得分:2)
承诺在捕获后继续,虽然您尝试在承诺中包含承诺,因此您可以手动更改行为,这是一种反模式。链接承诺本身会更好,所以你能够处理promise链中的错误,然后继续执行(所以中间的一个catch仍然可以跟随一个)。
不需要.catch(error => reject('LogIn failed.'))
,因为如果您只是从getSession()
返回承诺,那么底部的catch语句将捕获错误。你正在尝试创建自己的Promise,但是因为已经有getSession()
的回复,所以你真正想做的就是直接从中返回承诺。
最后,您在底部编写console.log
而不将其包装在回调函数中,因此在调用promise时同步触发,而不是在.then
触发时。
更简洁的解决方案是:
...
// return the promise from getSession, why wrap it in another?
return getSession()
.then(json => {
if (json.status === 'ok') {
return 'OK';
} else {
// Throwing an error in a then callback will trigger the catch block below
throw new Error('LogIn failed.');
}
});
}
logIn()
.then(() => console.log('logged in'))
.catch(error => console.log('not logged in'));
答案 2 :(得分:-1)
使用履行的履行价值或拒绝原因(视情况而定)调用onFulfilled或onRejected,并返回一个新的承诺,解析为被调用者的返回值。