为什么Async Await与React setState一起使用? [英] Why does Async Await work with React setState?

查看:439
本文介绍了为什么Async Await与React setState一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在ReactJS项目中一直在使用babel的async await.我发现可以方便地与React setState一起使用,我想更好地了解它.考虑以下代码:

I have been using async await with babel in my ReactJS project. I discovered a convenient use with React setState that I would just like to understand better. Consider this code:

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')    
}

我的目的是要在组件更新后运行异步验证代码.而且有效!生成的控制台日志显示:

My intention was for the asynchronous validation code to run after the component has updated. And it works! The resulting console log shows:

synchronous code
updated component
asynchronous validation code

仅在handleChange更新状态并呈现新状态后,验证代码才会运行.

The validation code will only run after handleChange has updated the state and the new state is rendered.

通常在状态更新后运行代码,您必须在this.setState之后使用回调.这意味着,如果要在handleChange之后运行任何内容,则必须为其提供一个回调参数,然后将其传递给setState.不漂亮.但是在代码示例中,等待状态以某种方式等待知道状态更新已完成...但是我认为等待仅适用于promise,并且等待promise解析后再继续.在handleChange中没有承诺,也没有解决方案...它如何知道要等待什么?

Usually to run code after state has updated, you would have to use a callback after this.setState. Which means if you want to run anything after handleChange, you have to give it a callback parameter which is then passed to setState. Not pretty. But in the code example, somehow await knows that handleChange is complete after the state has updated... But I thought await only works with promises and waits for a promise to resolve before continuing. Theres no promise and no resolution in handleChange... How does it know what to wait for??

似乎暗示setState是异步运行的,而await以某种方式知道它何时完成.也许setState在内部使用了Promise?

The implication seems to be that setState is run asynchronously and await is somehow aware of when it completes. Maybe setState uses promises internally?

版本:

反应:"^ 15.4.2"

react: "^15.4.2"

babel-core:"^ 6.26.0"

babel-core: "^6.26.0"

babel-preset-env:"^ 1.6.0",

babel-preset-env: "^1.6.0",

babel-preset-react:"^ 6.24.1",

babel-preset-react: "^6.24.1",

babel-preset-stage-0:"^ 6.24.1"

babel-preset-stage-0: "^6.24.1"

babel-plugin-system-import-transformer:"^ 3.1.0",

babel-plugin-system-import-transformer: "^3.1.0",

babel-plugin-transform-decorators-legacy:"^ 1.3.4",

babel-plugin-transform-decorators-legacy: "^1.3.4",

babel-plugin-transform-runtime:"^ 6.23.0"

babel-plugin-transform-runtime: "^6.23.0"

推荐答案

我尽力简化和补充戴文的答案,因此您可以更好地了解此处的实际情况:


  1. 等待放置在 this.handleChange 的前面,这将安排执行其余的 changeAndValidate >函数仅在等待 解析在其右侧指定的值时运行,在这种情况下,此值由 this.handleChange
  2. this.handleChange (位于等待右侧)执行:

  1. await is placed in front of this.handleChange, this will schedule the execution of the rest of changeAndValidate function to only run when await resolves the value specified to the right of it, in this case the value returned by this.handleChange
  2. this.handleChange, on the right of await, executes:

2.1. setState 运行其更新程序,但由于 setState 不保证立即更新,因此有可能将更新安排在以后的时间 (无关紧要)如果是即时的或在以后的某个时间点,那么所有的事情就是计划的时间)

2.1. setState runs its updater but because setState does not guarantee to update immediately it potentially schedules the update to happen at a later time (it doesn't matter if it's immediate or at a later point in time, all that matters is that it's scheduled)

2.2. console.log(同步代码")正在运行...

2.2. console.log('synchronous code') runs...

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

2.3. this.handleChange then exits returning undefined (returns undefined because functions return undefined unless explicitly specified otherwise)

等待,然后接受此未定义,由于它不是承诺,因此可以使用 Promise.resolve(undefined)<将其转换为已解决的承诺./strong>并等待它-它不会立即可用,因为它在后台传递给了它的 .then 方法,该方法是异步的:

await then takes this undefined and since it's not a promise it converts it into a resolved promise, using Promise.resolve(undefined) and waits for it - it's not immediately available because behind the scenes it gets passed to its .then method which is asynchronous:

传递给Promise的回调永远不会在 完成JavaScript事件循环的当前运行"

"Callbacks passed into a promise will never be called before the completion of the current run of the JavaScript event loop"

3.1.这意味着未定义将被放置在事件队列()的后面(这意味着它现在在事件队列的setState更新器后面…)

3.1. this means that undefined will get placed into the back of the event queue, (which means it’s now behind our setState updater in the event queue…)

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

  1. event loop finally reaches and picks up our setState update, which now executes...

事件循环到达并获取 undefined ,其结果为 undefined (如果需要,我们可以存储它,因此通常在await前面=用于存储已解决的结果)

event loop reaches and picks up undefined, which evaluates to undefined (we could store this if we wanted, hence the = commonly used in front of await to store the resolved result)

5.1. Promise.resolve()现在已完成,这意味着等待不再起作用,因此其余功能可以恢复

5.1. Promise.resolve() is now finished, which means await is no longer in affect, so the rest of the function can resume

这篇关于为什么Async Await与React setState一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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