Javascript 如何将.then.catch转换为异步/等待
使用React/Redux前端和我自己的nodejs/expressapi处理登录表单/注销按钮。登录表单有问题。大多数情况下,它工作得很好,但我经常会出错。第一个错误是禁止的,它告诉我用户在发送userDetails请求之前没有经过完全的身份验证 还有一个bug,Redux没有改变用户的角色,我需要动态地呈现nav。我认为将handleLogin转换为async/await将是解决方案,但我认为我做得不对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
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,但我很好奇这是否是生产质量应用程序的良好做法。@我建议您尽可能避免超时!这里的最佳实践是等待响应完成,而不是等待任意时间段过期。