为什么'if'条件没有在ajax调用的'then'承诺中得到评估?

raj*_*aan 1 javascript ajax callback promise reactjs

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

这是我第一次动手项目,请帮忙!提前致谢.

dan*_*dan 5

如果sessionStorage.getItem('isAuthenticated')按预期返回true,那么!sessionStorage.getItem('isAuthenticated')在你的速记条件中将评估false,因此&&不会得到评估之后的位


T.J*_*der 5

!sessionStorage.getItem('isAuthenticated') && x将仅评估x是否评估sessionStorage.getItem('isAuthenticated')值(因为您!在测试时用于反转该值)."true"这不是一个虚假的价值,它是一个真正的价值.

还有第二个问题:sessionStorage值总是字符串,所以你要存储,"true"并且"false"两者都是真正的值,而不是truefalse.

还有第三个问题:this在你的最终then处理程序中不会引用你期望它引用的内容,你可能想要使用箭头函数(或绑定函数).更多相关内容:http://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-context-inside-a-callback

所以最小的变化版本是:

  1. 转换"true""false"返回truefalse,和

  2. 摆脱!你的条件

  3. 使用箭头功能(或绑定功能).

我也建议实际使用if,而不是&&用于副作用.

所以例如(注意箭头功能):

.catch((error) => {
    console.log(sessionStorage.getItem('isAuthenticated')); //returns true as expected
    if (sessionStorage.getItem('isAuthenticated') === "true") {
        this.props.history.push("/");
    }
})
Run Code Online (Sandbox Code Playgroud)

但是,如果这真的是承诺链的结束,处理它的正确方法就是将其移动到您之前的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);
});
Run Code Online (Sandbox Code Playgroud)

但是,如果你在决赛中有其他事情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...
    }
});
Run Code Online (Sandbox Code Playgroud)

...但实际上将这两个分支放在thencatch处理程序(中间示例)中更有意义,而不是传播标志.