Javascript 如何将.then.catch转换为异步/等待

Javascript 如何将.then.catch转换为异步/等待,javascript,async-await,react-redux,Javascript,Async Await,React Redux,使用React/Redux前端和我自己的nodejs/expressapi处理登录表单/注销按钮。登录表单有问题。大多数情况下,它工作得很好,但我经常会出错。第一个错误是禁止的,它告诉我用户在发送userDetails请求之前没有经过完全的身份验证 还有一个bug,Redux没有改变用户的角色,我需要动态地呈现nav。我认为将handleLogin转换为async/await将是解决方案,但我认为我做得不对 import React from 'react'; import { login, u

使用React/Redux前端和我自己的nodejs/expressapi处理登录表单/注销按钮。登录表单有问题。大多数情况下,它工作得很好,但我经常会出错。第一个错误是禁止的,它告诉我用户在发送userDetails请求之前没有经过完全的身份验证

还有一个bug,Redux没有改变用户的角色,我需要动态地呈现nav。我认为将handleLogin转换为async/await将是解决方案,但我认为我做得不对

import React from 'react';
import { login, userDetails } from '../axios/homeApi';
import { useForm } from 'react-hook-form';
import { useDispatch } from 'react-redux';
import { setLogin, setRole } from '../redux/actions';
const LoginForm = () => {
const { handleSubmit, register, errors } = useForm();
const dispatch = useDispatch();

const handleLogin = values => {
    login(values.email, values.password)
    .then(res => {
        const token = res.data.token;
        window.localStorage.setItem('auth', token);
        dispatch(setLogin({ loggedIn: true }));
        userDetails()
        .then(res => {
            const role = res.data.data.role;
            dispatch (setRole({ role }));
        })
    })
}

return (
    <div>
        <form action="" onSubmit={handleSubmit(handleLogin)} className="footer-form">
            <input
                type="email"
                placeholder="Enter Email Here"
                name="email"
                ref={register({ required: "Required Field" })}
            />
            <input
                type="password"
                placeholder="Enter Password Here"
                name="password"
                ref={register({
                    required: "Required Field",
                    minLength: { value: 6, message: "Minimum Length: 6 Characters" }
                })}
            />
            {errors.password && errors.password.message}
            {errors.email && errors.email.message}
            <input type="submit" value="Login" />
        </form>
    </div>
)
}

export default LoginForm;

如果您在这方面有任何帮助/指导,我们将不胜感激。

当您使用wait时,您必须考虑,变量值与未使用wait返回到res中的值相同

因此,如果你有:

loginvalues.email,values.password .thenres=>{ } 这就像:

var login=wait loginvalues.email,values.password; 所以用这个逻辑,这个:

loginvalues.email,values.password .thenres=>{ const token=res.data.token; //随便 用户详细信息 .thenres=>{ const role=res.data.data.role; //随便 } } 变成:

var login = await login(values.email, values.password)
const token = login.data.token;
// do whatever
var userDetails = await userDetails()
const role = userDetails.data.data.role;
// whatever
检查此示例的工作原理。代码是一样的。一个使用。然后另一个使用等待

运行函数; 运行函数; 函数运行函数{ console.logEnter然后返回函数 this.returnPromise2000.thenres=>{ console.logres; this.returnPromise1000.thenres=>{ console.logres; }; }; //您可以在此处登录,并在承诺得到解决之前显示 console.logExit然后运行 } 异步函数runawait函数{ console.logEnter等待功能 var firstStop=等待返回承诺1000; console.logfirstStop var secondStop=等待返回承诺4000; console.logsecondStop //使用wait将停止代码,直到承诺得到解决 console.logExit等待功能 } 功能返回承诺时间{ 返回新PromiseSolve=>setTimeout=>resolvehello:+time+ms-later.,time;
} 当使用await时,必须考虑变量值与未使用await返回res的值相同

因此,如果你有:

loginvalues.email,values.password .thenres=>{ } 这就像:

var login=wait loginvalues.email,values.password; 所以用这个逻辑,这个:

loginvalues.email,values.password .thenres=>{ const token=res.data.token; //随便 用户详细信息 .thenres=>{ const role=res.data.data.role; //随便 } } 变成:

var login = await login(values.email, values.password)
const token = login.data.token;
// do whatever
var userDetails = await userDetails()
const role = userDetails.data.data.role;
// whatever
检查此示例的工作原理。代码是一样的。一个使用。然后另一个使用等待

运行函数; 运行函数; 函数运行函数{ console.logEnter然后返回函数 this.returnPromise2000.thenres=>{ console.logres; this.returnPromise1000.thenres=>{ console.logres; }; }; //您可以在此处登录,并在承诺得到解决之前显示 console.logExit然后运行 } 异步函数runawait函数{ console.logEnter等待功能 var firstStop=等待返回承诺1000; console.logfirstStop var secondStop=等待返回承诺4000; console.logsecondStop //使用wait将停止代码,直到承诺得到解决 console.logExit等待功能 } 功能返回承诺时间{ 返回新PromiseSolve=>setTimeout=>resolvehello:+time+ms-later.,time;
} 看起来您可能已经有了答案,但在我看来,这可能是因为您没有等待发送setLogin来完成。我不知道你的setLogin方法是如何设置的,但它必须是一个thunk。我发现下面的帖子很好地解释了这一点


看起来您可能已经有了答案,但在我看来,这可能是因为您没有等待发送setLogin来完成。我不知道你的setLogin方法是如何设置的,但它必须是一个thunk。我发现下面的帖子很好地解释了这一点


考虑任何具有then属性的对象,该属性是一个接受回调作为其第一个参数的函数,例如:

let obj = {
  then: callback => callback('hello')
};
wait将任何此类对象转换为值,然后提供给回调。因此:

(await obj) === 'hello'
在您的示例中,有两个实例要求将值返回给then回调:

login(...).then(res => { /* got res */ });

将wait简单地看作是将值返回到对象的回调的一种方式!在这种情况下,对象是登录的结果。。。和userDetails,您可以转换为:

let res = await login(...);

您可以看到,这也节省了大量缩进,这是人们喜欢使用async/await的众多原因之一

当插入到代码中时,这些从然后的回调值到等待值的转换如下所示:

const handleLogin = async values => {
  
  let loginRes = await login(values.email, values.password);
  let token = loginRes.data.token;
  window.localStorage.setItem('auth', token);
  dispatch(setLogin({ loggedIn: true }));
  
  let userDetailsRes = await userDetails();
  let role = userDetailsRes.data.data.role;
  dispatch(setRole({ role }));
  
};
请注意,该函数必须标记为async,并且我已将res重命名为更具体的名称,因为这两个响应现在存在于完全相同的名称中 范围,并且需要相互区分


总的来说,无论何时使用then在回调中获取某个值,都可以转换为更优雅的WAIT等价物。

考虑任何具有then属性的对象,该属性是一个接受回调作为其第一个参数的函数,例如:

let obj = {
  then: callback => callback('hello')
};
wait将任何此类对象转换为值,然后提供给回调。因此:

(await obj) === 'hello'
在您的示例中,有两个实例要求将值返回给then回调:

login(...).then(res => { /* got res */ });

将wait简单地看作是将值返回到对象的回调的一种方式!在这种情况下,对象是登录的结果。。。和userDetails,您可以转换为:

let res = await login(...);

您可以看到,这也节省了大量缩进,这是人们喜欢使用async/await的众多原因之一

当插入到代码中时,这些从然后的回调值到等待值的转换如下所示:

const handleLogin = async values => {
  
  let loginRes = await login(values.email, values.password);
  let token = loginRes.data.token;
  window.localStorage.setItem('auth', token);
  dispatch(setLogin({ loggedIn: true }));
  
  let userDetailsRes = await userDetails();
  let role = userDetailsRes.data.data.role;
  dispatch(setRole({ role }));
  
};
请注意,该函数必须标记为async,并且我已将res重命名为一个更具体的名称,因为这两个响应现在存在于完全相同的范围内,并且需要相互区分


总的来说,每当你使用回调中的某个值时,你就可以转换为更优雅的等待等价物。

调度是不可等待的。你应该考虑切换到TypeScript,因为了解类型的形状,知道什么是可等待的,什么是不重要的,使得编写现代JavaScript非常容易。调度是不可取的。你应该考虑切换到TypeScript,因为了解类型、形状,知道什么是可以等待的,什么是不可以等待的,这使得编写现代JavaScript变得非常容易。这几乎就是我所做的。仍在获取userDetails的禁止错误。const handleLogin=async values=>{let signin=await login values.email,values.password;const token=signin.data.token;window.localStorage.setItem'auth',token;dispatchsetLogin{loggedIn:true};const user=await userDetails;console.loguser.data.role;}我有另一个解决方案,但它不涉及这一点。这太神奇了。我将用这些知识重构一堆这个应用程序。这几乎就是我所做的。仍在获取userDetails的禁止错误。const handleLogin=async values=>{let signin=await login values.email,values.password;const token=signin.data.token;window.localStorage.setItem'auth',token;dispatchsetLogin{loggedIn:true};const user=await userDetails;console.loguser.data.role;}我有另一个解决方案,但它不涉及这一点。这太神奇了。我将用这些知识重构一堆应用程序。仍然会得到未经授权的错误。检查了瀑布,等待按预期工作。但我并没有从及时登录的庄园中获得所需的信息。设置超时可能是一种方法,因为登录调用平均需要4ms,但我很好奇这是否是生产质量应用程序的良好做法。@我建议您尽可能避免超时!这里的最佳实践是等待响应完成,而不是等待任意时间段过期。仍然会收到未经授权的错误。检查了瀑布,等待按预期工作。但我并没有从及时登录的庄园中获得所需的信息。设置超时可能是一种方法,因为登录调用平均需要4ms,但我很好奇这是否是生产质量应用程序的良好做法。@我建议您尽可能避免超时!这里的最佳实践是等待响应完成,而不是等待任意时间段过期。