Reactjs 异步/等待阻止执行第二个承诺

Reactjs 异步/等待阻止执行第二个承诺,reactjs,promise,async-await,try-catch,Reactjs,Promise,Async Await,Try Catch,假设我有一个登录功能 login = () => { let url = baseURL + '/user/login?_format=json'; let data = { "name": this.state.email, "pass": this.state.password }; return axios({ url, method: "POST", headers: {

假设我有一个登录功能

login = () => {
    let url = baseURL + '/user/login?_format=json';  

    let data = {
      "name": this.state.email,  
      "pass": this.state.password
    };


    return axios({
      url,
      method: "POST",
      headers: {
        'Accept':  'application/json',
        'Content-Type': 'application/json',
      },
      withCredentials: true,
      credentials: 'same-origin'
      })
      .then(function(result) {
        console.log('result:', result);
        this.setState({csrfToken: result.data.csrf_token}); 
        this.setState({logoutToken: result.data.logout_token});
        return result;
      })
      .catch(error => console.log('error:', error));
  }; 
然后我想在React中调用onSubmit函数,如下所示。如果函数因任何原因返回错误。如何防止在这种情况下运行下一个函数
api.login()

{api => (
            <Form
                onSubmit={async e => {
                  e.preventDefault();
                  await this.login();
                  api.login()
                }}
              >
    <input/>
    </Form>
{api=>(
{
e、 预防默认值();
等待此消息。login();
api.login()
}}
>

在这种情况下,try/catch有意义吗?我已经尝试了几个选项,包括内联try-catch,只要
this.login();
的承诺返回结果或错误,函数就会运行。

为什么不将
api.login()
放在第一个登录承诺
然后
回调中

login = () => {
let url = baseURL + '/user/login?_format=json';  

let data = {
  "name": this.state.email,  
  "pass": this.state.password
};


return axios({
  url,
  method: "POST",
  headers: {
    'Accept':  'application/json',
    'Content-Type': 'application/json',
  },
  withCredentials: true,
  credentials: 'same-origin'
  })
  .then(function(result) {
    console.log('result:', result);
    this.setState({csrfToken: result.data.csrf_token}); 
    this.setState({logoutToken: result.data.logout_token});
    api.login() // <----- if you want to check result just wrap it in an if statement if (result) api.login()
    return result;
  })
  .catch(error => console.log('error:', error));

为什么不把
api.login()
放在第一个登录承诺
中,然后再
回调

login = () => {
let url = baseURL + '/user/login?_format=json';  

let data = {
  "name": this.state.email,  
  "pass": this.state.password
};


return axios({
  url,
  method: "POST",
  headers: {
    'Accept':  'application/json',
    'Content-Type': 'application/json',
  },
  withCredentials: true,
  credentials: 'same-origin'
  })
  .then(function(result) {
    console.log('result:', result);
    this.setState({csrfToken: result.data.csrf_token}); 
    this.setState({logoutToken: result.data.logout_token});
    api.login() // <----- if you want to check result just wrap it in an if statement if (result) api.login()
    return result;
  })
  .catch(error => console.log('error:', error));

我认为这可能是因为您只是在catch方法中运行console.log,而不是抛出错误或拒绝承诺。因此,等待的try/catch块将继续运行,就好像一切正常一样。请尝试使用Promise.reject或new error()抛出错误

var catchwithout拒绝=async()=>{
wait console.log('hello')
console.log('running')
}
捕获而不拒绝();
//你好
//运行
//承诺{:未定义}
var catchWithRejection=async()=>{
等待承诺。拒绝(“你好”)
console.log('未运行')
}
捕捉拒绝();
//承诺{:“你好”}

我认为这可能是因为您只是在catch方法中运行console.log,而不是抛出错误或拒绝承诺。因此,等待的try/catch块将继续运行,就好像一切正常一样。请尝试使用Promise.reject或new error()抛出错误

var catchwithout拒绝=async()=>{
wait console.log('hello')
console.log('running')
}
捕获而不拒绝();
//你好
//运行
//承诺{:未定义}
var catchWithRejection=async()=>{
等待承诺。拒绝(“你好”)
console.log('未运行')
}
捕捉拒绝();
//承诺{:“你好”}

这是中提到的问题

登录的问题是它的控制流有缺陷。它无法有效地捕获错误,因为它会抑制错误

.catch(error=>console.log('error:',error))
抑制错误,而这不应该用于正确的控制流。拒绝应该在使用承诺的顶层处理。即使需要在
catch
中处理错误(根本不需要
console.log
),它应该被收回

异步错误的一致性处理是React中的一个单独问题。异步错误需要在生命周期挂钩中同步捕获和重新捕获(可能是
componentdiddupdate
):

componentDidUpdate(){
if(this.state&&this.state.error){
抛出这个.state.error;
}
}
onSubmit=async e=>{
试一试{
e、 预防默认值();
等待此消息。login();
api.login();
}捕捉(错误){
this.setState({error:err});
}
}
render(){
...
...
}
componentdiddupdate
中重试的错误将传播到错误边界组件,或者将导致异常


可能会引入一些额外的帮助程序来干燥
try{…}catch(err){this.setState({error:err})}
样板文件。

这是中提到的问题

登录的问题是它的控制流有缺陷。它无法有效地捕获错误,因为它会抑制错误

.catch(error=>console.log('error:',error))
抑制错误,而这不应该用于正确的控制流。拒绝应该在使用承诺的顶层处理。即使需要在
catch
中处理错误(根本不需要
console.log
),它应该被收回

异步错误的一致性处理是React中的一个单独问题。异步错误需要在生命周期挂钩中同步捕获和重新捕获(可能是
componentdiddupdate
):

componentDidUpdate(){
if(this.state&&this.state.error){
抛出这个.state.error;
}
}
onSubmit=async e=>{
试一试{
e、 预防默认值();
等待此消息。login();
api.login();
}捕捉(错误){
this.setState({error:err});
}
}
render(){
...
...
}
componentdiddupdate
中重试的错误将传播到错误边界组件,或者将导致异常


可能会引入一些额外的帮助程序来制作
try{…}catch(err){this.setState({error:err})}
样板文件。

您有第一个建议的示例吗?而且您未经测试的代码工作得非常好……我只是好奇为什么不放api.login()在第一个登录承诺内,然后是回调?我想这是因为
api
login
范围内不可用,并且这两个函数是解耦的。是的,这是一个鼓励重构选项的思考过程的问题。您有第一个建议的示例吗?您未经测试的代码也可以完美工作ly…我只是好奇为什么不把api.login()放在第一个登录承诺中,然后回调?我想这是因为
api
login
范围中不可用,并且这两个函数是解耦的。是的,这是一个鼓励重构选项的思考过程的问题
var catchWithoutRejection = async () => {
  await console.log('hello')
  console.log('running')
}

catchWithoutRejection();

// hello
// running
// Promise {<resolved>: undefined}

var catchWithRejection = async () => {
  await Promise.reject("hello")
  console.log('not running')
}

catchWithRejection();
// Promise {<rejected>: "hello"}
  componentDidUpdate() {
    if (this.state && this.state.error) {
      throw this.state.error;
    }
  }

  onSubmit = async e => {
    try {
      e.preventDefault();
      await this.login();
      api.login();
    } catch (err) {
      this.setState({ error: err });
    }
  }

  render() {
    ...
    <Form onSubmit={this.onSubmit}>
      <input/>
    </Form>
    ...
  }