当前位置: 首页 > 知识库问答 >
问题:

为什么Async Wait与React setState一起工作?

马边浩
2023-03-14

在我的ReactJS项目中,我一直在使用AsyncWait和babel。我发现React setState有一个方便的用法,我只是想更好地理解它。考虑这个代码:

handleChange = (e) => {
  this.setState({[e.target.name]: e.target.value})
  console.log('synchronous code')
}

changeAndValidate = async (e) => {
  await this.handleChange(e)
  console.log('asynchronous validation code')
}

componentDidUpdate() {
  console.log('updated component')    
}

我的意图是让异步验证代码在组件更新后运行。它工作了!生成的控制台日志显示:

synchronous code
updated component
asynchronous validation code

验证代码仅在handleChange更新状态并呈现新状态后运行。

通常,要在状态更新后运行代码,必须在this.set状态后使用回调。这意味着如果你想在handleChange之后运行任何东西,你必须给它一个回调参数,然后传递给setState。不漂亮。但是在代码示例中,不知何故,等待知道在状态更新后HandleChange已经完成...但是我认为等待只能和promise一起工作,并且在继续之前等待promise的解决。没有promise,也没有解决办法。它怎么知道要等什么??

这似乎意味着setState是异步运行的,而wait在某种程度上知道它何时完成。也许setState在内部使用promise?

版本:

反应:"^15.4.2"

巴别塔核心:“^6.26.0”

Babel-preet-env:"^1.6.0",

巴别塔预设反应:“^6.24.1”,

巴别塔-preset-stage-0:“^6.24.1”

Babel-plugin-system导入变压器:"^3.1.0",

babel插件转换装饰html" target="_blank">程序传统:“^1.3.4”,

babel插件转换运行时:“^6.23.0”

共有3个答案

秦景福
2023-03-14

setState()并不总是立即更新组件文档

但这里可能是这样。

如果你想用一个promise替换回调,你可以自己实现它:

setStateAsync(state) {
  return new Promise((resolve) => {
    this.setState(state, resolve)
  });
}

handleChange = (e) => {
  return this.setStateAsync({[e.target.name]: e.target.value})
}

裁判:https://medium.com/front-end-hacking/async-await-with-react-lifecycle-methods-802e7760d802

路雅懿
2023-03-14

我还没有测试过这一点,但以下是我认为正在发生的事情:

wait返回的undefinedsetState回调后排队。await正在执行下面的Promise.resolve(在再生器运行时中),这反过来会产生对事件循环上下一项的控制。

所以,setState回调恰好排在wait之前,这是巧合。

您可以通过设置setTimeout(f=

babel中的再生器运行时本质上是一个使用Promise.resolve来产生控制的循环。您可以看到_asyncToGenerator的内部,它有一个Promise.resolve

陆洲
2023-03-14

>

  • wait被放置在this.handleChange的前面,这将安排执行的Change eAndValester函数的其余部分,只有当wait解决了它的右边指定的值,在这种情况下返回的值this.handle更改
  • this.handle更改,在等待的右边,执行:

    2.1. setState运行其更新程序,但由于setState不保证立即更新,因此它可能会将更新安排在稍后的时间进行(无论是立即更新还是在稍后的时间点进行更新,重要的是它的计划)

    2.2. console.log(“同步代码”)正在运行。。。

    2.3. 然后,this.handleChange退出返回undefined(返回undefined,因为除非另有明确指定,否则函数返回undefined)

    Wait然后接受这个未定义的,因为它不是一个promise,它将它转换成一个解决的promise,使用Promise.resolve(未定义)并等待它——它不能立即可用,因为在幕后它会传递给它的。

    “在当前JavaScript事件循环运行完成之前,不会调用传递到promise中的回调”

    3.1. 这意味着undefined将被放在事件队列的后面(这意味着它现在位于事件队列中setState更新程序的后面…)

    事件循环最终到达并拾取我们的setState更新,现在执行...

    事件循环到达并拾取undefined,其计算结果为undefined(如果需要的话,我们可以存储它,因此在wait前面通常使用=来存储解析的结果)

    5.1. resolve()现在已完成,这意味着wait不再生效,因此函数的其余部分可以继续

  •  类似资料:
    • 服务被调用,但我的问题是这行代码 不起作用,我的意思是它真的调用了adminDao。选择方法,从而从数据库中获取结果。这是我不想要的。你知道如何模拟方法调用吗?

    • 我在试着为Spock中的控制器写一个测试。 应用程序类只是Spring Boot最简单的配置(支持自动扫描)。它提供了一个with PasswordEncryptor。我想用提供模拟的bean替换应用程序中的这个bean。 没有注释,所以Spring不知道应该注入哪个bean。不幸的是,我不知道如何让Spring通过本地配置从应用程序中替换bean。

    • 我正在使用karaf 3.0.3和以下Hibernate捆绑包: 161|活动|80|;4.2.12.Final|hibernate core 162124活动#80 1244.1.12.Final124Hibernate entitymanager 172| 124活动80#4.2-12.fin 通过这种设置,我无法让事务回滚正常工作,尽管我可以将完全相同的组件(JPA DAO、服务层等)部署为

    • 当在嵌入了tomcat的spring boot中运行代码时,Spring cloud consul可以像预期的那样工作。 当我们在独立的tomcat上部署代码时,它不起作用。似乎有一个Web服务器上启动领事服务注册。仅当我们在带有嵌入式 tomcat 的Spring启动内运行代码时,才会触发此事件。 https://github.com/spring-cloud/spring-cloud-cons

    • css在中不工作,但使用此css代码。我在css区域和html标记中首先编写,然后编写。为什么? CSS HTML

    • 我正在启动一个基于Stephan Zerhusen出色的SpringBoot JWT演示的项目。它在我的SpringToolSuite项目中安装并运行良好。我对它的进一步开发遇到了问题。 我想将Stephan的代码(org.zerhusen)与我的业务逻辑(com.mypackage)分开。我尝试过的@SpringBootApplication和@ComponentScan配置都不适用于我。 Sp