我一直在我的 ReactJS 项目中使用 async wait 和 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.setState 之后使用回调。这意味着如果你想在handleChange之后运行任何东西,你必须给它一个回调参数,然后将其传递给setState。不漂亮。但在代码示例中,不知何故,await 知道在状态更新后handleChange 已完成...但我认为await 只能与promise 一起使用,并在继续之前等待promise 解决。在handleChange 中没有 promise 也没有解决方案...它如何知道要等待什么?
这似乎意味着 setState 是异步运行的,并且 wait 以某种方式知道它何时完成。也许 setState 在内部使用了 Promise?
版本:
react :“^15.4.2”
babel-core:“^6.26.0”
babel-preset-env: "^1.6.0",
babel-preset-react: "^6.24.1",
babel-preset-stage-0:“^6.24.1”
babel-plugin-system-import-transformer:“^3.1.0”,
babel-plugin-transform-decorators-legacy: "^1.3.4",
babel-plugin-transform-runtime:“^6.23.0”
最佳答案
我尽力简化和补充 Davin 的答案,以便您可以更好地了解这里实际发生的情况:
<小时/>- await 放在 this.handleChange 前面,这将安排执行 changeAndValidate 的其余部分> 函数仅在 await 解析 其右侧指定的值时运行,在本例中为 this.handleChange 返回的值
this.handleChange,在await右侧,执行:
2.1。 setState 运行其更新程序,但由于 setState 不保证立即更新,因此可能会安排稍后进行更新(这并不重要如果是立即发生或稍后发生,重要的是它是已安排的)
2.2。 console.log('同步代码') 运行...
2.3。 this.handleChange 然后退出,返回 未定义 (返回未定义,因为除非明确指定,否则函数返回未定义)
await 然后接受这个 undefined ,因为它不是一个 promise ,所以它使用 Promise.resolve(undefined)< 将其转换为已解决的 promise 并等待它 - 它不会立即可用,因为它在幕后传递给异步的 .then 方法:
“Callbacks passed into a promise will never be called before the completion of the current run of the JavaScript event loop”
3.1。这意味着未定义将被放置到事件队列的后面,(这意味着它现在位于事件队列中我们的setState更新程序后面......)
事件循环最终到达并获取我们的setState更新,现在执行...
事件循环到达并获取未定义,其计算结果为未定义(如果我们想要的话,我们可以存储它,因此通常在await前面使用=来存储解析的结果)
5.1。 Promise.resolve() 现已完成,这意味着 await 不再有效,因此函数的其余部分可以恢复
- 您的验证代码运行
关于reactjs - 为什么 Async Await 可以与 React setState 配合使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47019199/