javascript - 为什么在 ajax 调用的 'then' 承诺中没有评估 'if' 条件?
问题描述
我有一个 ajax 调用,最后我有一个“then”承诺,其中我可以看到控制台日志在出现错误时返回 false,但在下一行中似乎没有评估 if 条件。
我已将以下代码中的条件注释为“未评估”。
请参考以下代码:
authenticate(email, password){
const encodedEmail = encodeURIComponent(email);
console.log(encodedEmail);
axios.get(`http://localhost:8080/api/users/${encodedEmail}`,{
headers: {
'Access-Control-Allow-Origin': '*',
Authorization: 'Basic ' + btoa(email + ":" + password)
}
})
.then(function (response) {
console.log(response);
sessionStorage.setItem('isAuthenticated', true);
})
.catch(function (error) {
console.log(error);
sessionStorage.setItem('isAuthenticated', false);
}).then(() => {
console.log(sessionStorage.getItem('isAuthenticated')); //returns true as expected
!sessionStorage.getItem('isAuthenticated')
&& this.props.history.push("/"); // not evaluated
});
}
handleLogIn(e){
e.preventDefault();
const email = e.target.elements.email.value;
const password = e.target.elements.password.value;
this.authenticate(email, password);
this.props.dispatch(addCredentials({email, password}));
}
这是我第一次动手做项目,请帮忙!提前致谢。
解决方案
!sessionStorage.getItem('isAuthenticated') && x
只会评估x
是否评估sessionStorage.getItem('isAuthenticated')
为虚假值(因为您!
在测试时用于反转该值)。"true"
不是一个虚假的价值,它是一个真实的价值。
还有第二个问题:sessionStorage
值总是字符串,所以你要存储"true"
and "false"
,它们都是真实值,而不是true
and false
。
还有第三个问题:this
在您的最终then
处理程序中不会引用您期望它引用的内容,您可能想要使用箭头函数(或绑定函数)。更多信息在这里:http ://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-context-inside-a-callback
所以最小更改版本是:
将
"true"
or转换"false"
回true
orfalse
, 和摆脱
!
你的状况使用箭头函数(或绑定函数)。
我还建议实际使用if
,而不是使用&&
副作用。
例如(注意箭头功能):
.catch((error) => {
console.log(sessionStorage.getItem('isAuthenticated')); //returns true as expected
if (sessionStorage.getItem('isAuthenticated') === "true") {
this.props.history.push("/");
}
})
但如果这真的是 Promise 链的结尾,那么处理它的正确方法就是将它移到您之前的then
处理程序中(注意箭头函数):
axios.get(`http://localhost:8080/api/users/${encodedEmail}`,{
headers: {
'Access-Control-Allow-Origin': '*',
Authorization: 'Basic ' + btoa(email + ":" + password)
}
})
.then((response) => {
console.log(response);
sessionStorage.setItem('isAuthenticated', true);
this.props.history.push("/"); // <==================
})
.catch((error) => { // Doesn't have to be an arrow, but if you relocate any code...
console.log(error);
sessionStorage.setItem('isAuthenticated', false);
});
但是,如果您在 final 中还有其他事情要做then
,我会通过承诺链传播标志,而不是回到sessionStorage
它:
axios.get(`http://localhost:8080/api/users/${encodedEmail}`,{
headers: {
'Access-Control-Allow-Origin': '*',
Authorization: 'Basic ' + btoa(email + ":" + password)
}
})
.then((response) => {
console.log(response);
sessionStorage.setItem('isAuthenticated', true);
return true;
})
.catch((error) => {
console.log(error);
sessionStorage.setItem('isAuthenticated', false);
return false;
})
.then((isAuthenticated) => {
if (isAuthenticated) {
this.props.history.push("/");
} else {
// do the other thing...
}
});
...但实际上将这两个分支放在then
andcatch
处理程序中(中间示例)比传播标志更有意义。
推荐阅读
- acumatica - 从约会生成发票的 GL 错误
- angular - Angular HttpClient 发布请求类型
- html - Bootstrap4 在列中获取卡片以水平和垂直拉伸和填充父容器
- javascript - 表之间的sequelize和query
- php - 试图从 $_SESSION foreach 循环 PHP 中获取索引
- java - 如何使用pdfbox获取pdf中选定文本的字体信息
- java - 如何使用 xpath 作为 sendkeys 从 selenium 上传只读文本文件将不起作用
- java - 二十一点代码中涉及 A 的逻辑错误
- jquery - 如何使用引导模型对话框将数据添加到数据表?
- xamarin - 如何在 MvvmCross 6.0 中指定使用来自共享项目的视图