如何将 .then .catch 转换为 async/await [英] How to convert .then .catch to async/await

查看:18
本文介绍了如何将 .then .catch 转换为 async/await的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 React/Redux 前端和我自己的 nodejs/express api 处理登录表单/注销按钮.登录表单有问题.大多数时候它工作得很好,但我经常遇到错误.第一个错误是 forbidden,它告诉我用户在发送 userDetails 请求之前没有完全通过身份验证.

然后还有一个 bug,Redux 没有改变用户的角色,我需要动态渲染导航.我认为将 handleLogin 转换为 async/await 将是解决方案,但我相信我做得不对.

从'react'导入React;从'../axios/homeApi'导入{登录,用户详细信息};导入 { useForm } from 'react-hook-form';从'react-redux'导入{useDispatch};import { setLogin, setRole } from '../redux/actions';const LoginForm = () =>{const { handleSubmit, register, errors } = useForm();const dispatch = useDispatch();const handleLogin = 值 =>{登录(值.电子邮件,值.密码).then(res => {const token = res.data.token;window.localStorage.setItem('auth', token);调度(setLogin({登录:真}));用户详细信息().then(res => {const 角色 = res.data.data.role;调度(setRole({角色}));})})}返回 (<div><form action=""onSubmit={handleSubmit(handleLogin)} className=footer-form"><输入类型=电子邮件"placeholder =在此处输入电子邮件"名称=电子邮件"ref={register({ 必填:必填字段"})}/><输入类型=密码"placeholder="在此处输入密码";名称=密码"ref={注册({必填:必填字段",minLength: { value: 6, message: "Minimum Length: 6 Characters";}})}/>{errors.password &&错误.密码.消息}{errors.email &&错误.email.message}<输入类型=提交"值=登录"/></表单>

)}导出默认登录表单;

这是我将 handleLogin 转换为 async/await 的最佳尝试.我试图了解我应该如何从这些调用中提取数据.

const handleLogin = 异步值 =>{尝试 {const {data: {token}} = await login(values.email, values.password)window.localStorage.setItem('auth', token);控制台日志(令牌);const user = await userDetails();等待调度(setLogin({登录:真}))等待调度(setRole(user.data.data.role))} 抓住(错误){控制台日志(错误)}}

对此的任何帮助/指导将不胜感激.

解决方案

你得想想,当你使用await时,变量值和返回到res中的值是一样的无需await.

如果你有:

登录(values.email, values.password).then(res => {})

这就像:

var login = await login(values.email, values.password);

所以使用这个逻辑,这个:

登录(values.email, values.password).then(res => {const token = res.data.token;//任何用户详细信息().then(res => {const 角色 = res.data.data.role;//任何})})

变成:

var login = await login(values.email, values.password)const token = login.data.token;//做任何事var userDetails = 等待 userDetails()const 角色 = userDetails.data.data.role;//任何

检查这个例子是如何工作的.代码是相同的".一个使用 .then,另一个使用 await.

runThenFunction();运行等待函数();函数 runThenFunction(){console.log("输入然后函数")this.returnPromise(2000).then(res => {控制台日志(res);this.returnPromise(1000).then(res => {控制台日志(res);});});//这里可以登录,在promise解决前会显示console.log("退出然后函数")}异步函数 runAwaitFunction(){console.log("进入等待函数")var firstStop = await returnPromise(1000);控制台日志(第一次停止)var secondStop = await returnPromise(4000);控制台日志(第二次停止)//使用 await 代码停止"直到 promise 被解决console.log("退出等待函数")}函数返回承诺(时间){return new Promise(resolve => setTimeout(() => resolve("hello: "+time+"ms later."), time));}

Working on a login form / logout button with React/Redux front end and my own nodejs/express api. Having an issue with the login form. Most of the time it works just fine, but I'm getting erros on a regular basis. First error is forbidden, which tells me that the user is not quite authenticated before send the userDetails request.

Then there's another bug where Redux doesn't change the role of the user, which I need to dynamically render the nav. I'm thinking converting handleLogin to async/await will be the solution, but I believe I'm not doing it right.

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;

Here's my best attempt at converting handleLogin to async/await. I'm trying to understand how I'm supposed to pull data from these calls.

const handleLogin = async values => {
    try {
        const {data: {token}} = await login(values.email, values.password)
        window.localStorage.setItem('auth', token);
        console.log(token);
        const user = await userDetails();
        await dispatch(setLogin({ loggedIn: true}))
        await dispatch(setRole(user.data.data.role))
    } catch(err) {
        console.log(err)
    }
}

Any help/guidance on this would be greatly appreciated.

解决方案

You have to think when you use await, the variable value is the same that returned into res without await.

So if you have:

login(values.email, values.password)
    .then(res => { 
     })

This is like:

var login = await login(values.email, values.password);

So using this logic, this:

login(values.email, values.password)
    .then(res => {
        const token = res.data.token;
        // whatever
        userDetails()
        .then(res => {
            const role = res.data.data.role;
            // whatever
        })
    })

Turn into:

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

Check how works this example. The code is "the same". One using .then and the other using await.

runThenFunction();

runAwaitFunction();

function runThenFunction(){
  console.log("Enter then function")
  this.returnPromise(2000).then(res => {
    console.log(res);
    this.returnPromise(1000).then(res => {
      console.log(res);
    });
  });
  //You can log here and it will be displayed before the promise has been resolved
  console.log("Exit then function")
}

async function runAwaitFunction(){
  console.log("Enter await function")
  var firstStop = await returnPromise(1000);
  console.log(firstStop)
  var secondStop = await returnPromise(4000);
  console.log(secondStop)
  // Using await the code "stops" until promise is resolved
  console.log("Exit await function")
}

function returnPromise(time){
  return new Promise(resolve => setTimeout(() => resolve("hello: "+time+"ms later."), time));
}

这篇关于如何将 .then .catch 转换为 async/await的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆