Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React似乎同时执行两个功能_Javascript_Reactjs - Fatal编程技术网

Javascript React似乎同时执行两个功能

Javascript React似乎同时执行两个功能,javascript,reactjs,Javascript,Reactjs,我做了一个简单的石头剪刀布游戏。在onclick期间,我调用一个函数来添加一个数字并更改状态。在该函数中,我再调用2个函数,一个函数选择1到3之间的随机数,将其转换为石头/布/剪刀,并将其分配给状态,然后另一个函数计算出谁获胜: addToInput = val =>{ this.setState({ input:val }); this.picknum(); this.pickwin(); } 起初我以为picknum

我做了一个简单的石头剪刀布游戏。在
onclick
期间,我调用一个函数来添加一个数字并更改状态。在该函数中,我再调用2个函数,一个函数选择1到3之间的随机数,将其转换为石头/布/剪刀,并将其分配给状态,然后另一个函数计算出谁获胜:

addToInput = val =>{
    this.setState({ 
        input:val
    });

    this.picknum();
    this.pickwin();       
}

起初我以为
picknum
pickwin
会同时执行,但是即使我尝试在
picknum
中调用
pickwin
,它仍然无法工作

似乎发生的情况是,当执行
pickwin
时,它会查看旧状态,而不是由
picknum
更改的状态


如何解决此问题?

这是javascript的异步机制

 this.setState({ 

    input:val


  });
如果你想同步。让我们使用异步/等待。 这是我的密码:

 addToInput = async val =>{
   // console.log('add function');

 await this.setState({ 

    input:val


  });
   await this.picknum();
  await this.pickwin();

 } 
让我们试试吧

setState是异步的(或者至少可以是异步的),因此,如果在设置状态后需要运行某些东西,则无法保证在进入下一行代码时状态已经更新,或者将其放入componentDidUpdate生命周期挂钩,或者将回调作为第二个参数传递到setState

例如,您可以跳过addToInput函数中的pickWin操作,而使用componentDidUpdate函数,如下所示:

componentDidUpdate(prevProps, prevState) {
  this.pickWin();
}
也就是说,我建议您重构代码,只调用setState一次,而不是设置状态,然后等待它更新,然后再次设置状态。如果多次调用,可能会导致多次渲染,但看起来这些渲染都是同一操作的一部分。也许更新pickNum和pickWin函数以返回值,而不是设置状态本身,然后使用结果调用setState一次

picknum () {
  let aipick = ["rock","paper","scisors"];   
  let temp = Math.floor(Math.random() * 3) + 0  ;
  return aipick[temp]
}

pickWin(userChoice, aiChoice) {
  if (userChoice === 'rock' && aiChoice == 'scisors') {
    return 'USER WINS';
  }
  // etc
}

addToInput = val => {
  let aiChoice = pickNum();
  let winner = pickWin(val, aiNum);
  this.setState({
    aiChoice: aiChoice,
    whowon: winner,
    input: val,
  })
}

好的,看来回调可能是解决方案之一,所以我试着这么做

  picknum (){

     let aipick=["rock","paper","scisors"];   
      let temp =Math.floor(Math.random() * 3) + 0  ;
  this.setState({
    aichoice:aipick[temp]
  },function(){
   this.pickwin();
 }
               )


}




  ////////////
addToInput = val =>{
   // console.log('add function');

 this.setState({ 

    input:val


  },function(){
   this.picknum();
 }

              );


 } 

现在似乎可以工作了。

显示picknum()和pickwind()有趣代码的可能重复项。setState确实是(或可以是)异步的,但是它不会返回承诺,所以wait不会有帮助。似乎已经解决了问题,除非我遗漏了一些东西等待一个不承诺只会将代码延迟到下一个微任务,并且不能保证它会等待你认为你正在等待的东西。如果adding Wait修复了问题,那么您就幸运了。这不是解决这类问题的正确方法。那么如何解决这类问题呢。我想如果把所有东西都显示在一个函数中,只使用一个setstate,它会修复它,但是有没有其他方法来修复它谢谢你,我尝试过回调一个,现在似乎可以了。