异步等待setstate并返回promise

时间:2019-02-28 07:19:29

标签: javascript reactjs asynchronous promise async-await

1)我试图更好地理解async await。我有个想法,就是在setState函数中设置await .then(//setState)可以照顾setState的异步特性,但是在运行一些测试后,似乎并非如此。

constructor(){
   this.state = { msg: 'ZERO' }
}

async componentDidMount() {
    await this.setter();
    this.setState({ msg: 'TWO' });

    console.log('AFTER', this.state.msg) //Logs TWO
}

setter = () => {
    this.setState({ msg: 'ONE' }, () => console.log('INSIDE', this.state.msg)); //Logs ONE
    console.log('BOTTOM', this.state.msg) //Logs ZERO
    return Promise.resolve();
}

setter() BOTTOM中的日志显示ZERO,这表明setState的异步性质。即使在日志之前将状态设置为ONE,它也会显示默认值ZERO。我不了解的部分是,当Promise返回并且setState之后再次发生await this.setter()时,日志AFTER将显示TWO。这不应该是ONE,因为setState中的setter来自await,则之后的setState不会包含在promise或await中,而是{{ 1}}日志仍显示正确的值。为什么?

2)关于异步等待的另一个问题是承诺的返还。当我不返回AFTER时,它将显示错误Promise.resolve()。但是,我有一个uncaught promise, cannot read property of then函数,它将在传入的prop函数上应用await,该函数不会返回onSubmit但错误不会显示。

//组分A

Promise.resolve()

//成分B

onSubmit = async () => {
    await this.props.passedInFunction(1);
}

如您所见,passedInFunction = (num) => this.setState({value: num}); 中的passedInFunction并未返回COMPONENT B,但由于某种原因,在我的应用程序中,当在Promise.resolve中调用该函数时,未捕获的承诺错误不会显示。

编辑:忘记在COMPONENT A前面添加await

1 个答案:

答案 0 :(得分:0)

该行为取决于您如何使用异步等待。

要注意的一件事是await在异步函数中起作用。其次,如果您使用await来等待非异步功能。 根据{{​​3}}

  

如果该值不是Promise,则会将其转换为已解析的值   答应,然后等待。

因此您无需从Promise.resolve()方法中返回setter,并且

onSubmit = async () => {
    await this.props.passedInFunction(1);
}

async componentDidMount() {
    await this.setter();
    this.setState({ msg: 'TWO' });

    console.log('AFTER', this.state.msg) //Logs TWO
}

都可以正常工作。

  

现在要说明为什么console.log('AFTER', this.state.msg)   返回两个。

setState是异步的,它不能保证该更新将立即可见,但也不能告诉您该更新将永远不会立即可见。

在您的情况下,setState调用是componentDidUpdate中的最后一个调用,不会进行批处理,因此它将立即更新。这样一来,就无法保证将来您会编写一些代码,并且这种行为不再成立。

MDN docs