简体   繁体   English

此异步等待不应该工作。 为什么它会起作用?

[英]This Async Await should not be working. Why is it working then?

So I have been doing React-Native for a couple months now and I stumbled upon a situation where a huge chunk had to be updated in setState function.所以我一直在做 React-Native 几个月了,我偶然发现了一个很大的块必须在 setState function 中更新的情况。 I had to call a function afterward that was dependent on that state.之后我不得不调用 function,这取决于 state。 Of course the state didn't mutate right away since I learned that setState is Asynchronous.当然,state 并没有立即发生变异,因为我了解到 setState 是异步的。

This is my structure这是我的结构

Parent家长

stateSetter = (data) => {
        this.setState({
            ...data
        })
    }
dateFilter = () => {
        let startDate = this.state.startDate
        let endDate = this.state.endDate
        if (startDate !== "" && endDate == "") {
            this.setState({
                DataFiltered: this.state.Data.filter(elem => Helper.convertDateToISO(elem.date)>= Helper.convertDateToISO(startDate))
            })
        }else if(startDate == "" && endDate !== ""){
            this.setState({
                DataFiltered: this.state.Data.filter(elem => Helper.convertDateToISO(elem.date)<= Helper.convertDateToISO(endDate))
            })
        }else if(startDate !== "" && endDate !== ""){
            this.setState({
                DataFiltered: this.state.Data.filter(elem => Helper.convertDateToISO(elem.date)>= Helper.convertDateToISO(startDate) && Helper.convertDateToISO(elem.date)<= Helper.convertDateToISO(endDate))
            })
        }else if(startDate === "" && endDate === ""){
            this.setState({
                DataFiltered: this.state.Data
            })
        }
    }

Child孩子

<TouchableWithoutFeedback onPress={async () => {
                await stateSetter({
                    ["startDate"]: "",
                    ["endDate"]: "",
                    ["startDateText"]: "From...",
                    ["endDateText"]: "To..."
                })
                dateFilter()
            }} >

Now I was under the belief that Async Await works only when await is waiting for a promise.....right?现在我相信 Async Await在 await 等待 promise 时才有效......对吗? So by that logic, in the aforementioned code, await and async should have no effect on the program.所以按照这个逻辑,在上述代码中,await 和 async 应该对程序没有影响。

au contraire非盟

When I don't use async await, it doesn't work.当我不使用异步等待时,它不起作用。 It only works when I use async await.它仅在我使用异步等待时才有效。

When I was just learning about async, I tried a couple things and none of them worked.当我刚刚学习异步时,我尝试了几件事,但都没有奏效。

this.setState({ ...data }, () => {
  this.dateFilter()
})
//Had no effect

Also: Promise had no effect.另外:Promise 没有效果。

TlDr: Why is my Async Await working? TlDr:为什么我的 Async Await 工作正常?

  1. await ins your sample won't work as expected as stateSetter not returning an promise等待您的示例无法按预期工作,因为 stateSetter 未返回 promise

To make await applicable for stateSetter it must return an Promise要使等待适用于 stateSetter,它必须返回 Promise

stateSetter = (data) => {
   return new Promise(resolve => setTimeout(resolve, 3000));
}
  1. Checkout this pretty good explanation about what's going on here看看这个关于这里发生了什么的很好的解释

tl;dr: Because you are using await , the rest of the function is scheduled to be executed in the future and at that point in time the state will have been updated. tl;dr:因为您正在使用await ,所以 function 的 rest 计划在未来执行,届时 Z9ED39E2EA931586B6A985A6942EF573E 将被更新。 Whether or not you are actually await ing a promise is irrelevant.您是否真的await promise 无关紧要。


I don't know the internals of React, but I assume the queue a micro task to update the state.我不知道 React 的内部结构,但我假设队列是一个微任务来更新 state。 Promise callbacks are also processed as a micro task (and async/await is just a nice way to work with promises). Promise 回调也作为微任务处理(并且async/await只是使用 Promise 的好方法)。

So first React adds a micro task to update the state, and then await adds a micro task for resuming the function.所以首先 React 添加了一个微任务来更新 state,然后await添加了一个微任务来恢复 function。

We can actually do a simple experiment to verify what the order of events is by passing a callback to setState (no JSX because somehow I couldn't make it a working snippet):我们实际上可以做一个简单的实验,通过将回调传递给setState来验证事件的顺序(没有 JSX,因为不知何故我无法使其成为工作片段):

 class Component extends React.Component { async doStuff() { await this.setState({newState: true}, () => console.log('inside setState callback', JSON.stringify(this.state))); console.log('after await this.setState', JSON.stringify(this.state)); } render() { return React.createElement('button', {onClick: () => this.doStuff()}, 'Click me'); } } ReactDOM.render( React.createElement(Component), document.body );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

If you run this you will see that the callback gets called first.如果你运行它,你会看到回调首先被调用。 We know that the state has been updated at this point because that's the whole purpose of the callback: It is executed when the state has been updated.我们知道此时 state 已经更新,因为这就是回调的全部目的:它在 state 更新时执行。

Then the remainder of the function is executed, and since the state has already been updated, it will be accessing the new state.然后执行 function 的其余部分,由于 state 已经更新,它将访问新的 state。

However, since you are were wondering yourself why this works, I would recommend against this practice and just use the setState callback.但是,由于您想知道为什么会这样,我建议您不要使用这种做法,而只使用setState回调。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM