es7 async await 为什么会对react setState起作用?

发布于 2022-09-06 11:49:52 字数 1274 浏览 58 评论 0

es7 async await 为什么会对react setState起作用?setState()并不是一个promise啊!?下面是代码和日志

constructor(props){
        super(props);
        this.state={
            value:this.props.value||this.props.defaultValue||'',
            result:true,
        }
    }   

    verifier(){

        let result;
        let{rules} = this.props;
        let{value} = this.state;

        switch (this.rulesClassify()){
            case 'fn' :
                result = rules();
                break;
            case 'reg' :
                result = rules.test(value);
                break;
            default :
                result = rules===value;
        }

        this.setState({
            result
        });

    }



    /*
    **
    @每次变动callback
    */
    async handleChange(event){

        //受控
        let value=event.target.value;

        await this.setState({
            value
        });

        debug(this.state.result);
        //验证
        await this.verifier();

        debug(this.state.result);

    }

图片描述

这里验证了input中只能是存数字,当我输入非数字时,如果没有使用 async和await的时候log就会输出两个true,而当使用async和await时,则是上图结果,说明async和await起了作用

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

固执像三岁 2022-09-13 11:49:52

答案有了。
1、非常冒昧的去直接询问了@司徒正美 老师,老师的答案是巧合。
2、stackoverflow 上也找到了答案 Why does Async Await work with React setState? (具体看 Davin Tryon的回答 关于regenerator-runtime中_asyncToGenerator)
3、如何合理的解决setState异步带来的困扰,也许大家需要浏览一下这两篇文章,文章里包含了关于setState的官方推荐姿势和为什么setState不返回promise 从 setState promise 化的探讨 体会 React 团队设计思想
setState:这个API设计到底怎么样

落墨 2022-09-13 11:49:52

await不仅能等待Promise,也可以等待任意表达式的结果,如异步函数的返回值等。
具体找了篇文章你哭看下。
理解 JavaScript 的 async/await

幸福还没到 2022-09-13 11:49:52

虽然是个老问题了,但还是忍不住回答一下。
实际上不是await对setState生效,而是async改变了handleChange这个方法,关于async/await做了什么,源码太麻烦了,我参考了简书上的一篇文章:JavaScript 的 async/await : async 和 await 在干什么
async函数最终会返回一个Promise,而await会等待后面的执行结束后用Promise.resolve包裹一下,将后面的代码包裹在then里面。

那么await为什么会对setState起效呢?我参考了一下react-lite(后面统称为react)的实现后豁然开朗。
react中调用setState的地方无疑只有两个,一个是生命周期钩子函数,一个是合成事件,两者情况基本上一致,以下图为例。

clipboard.png
在执行componentDidMount之前,整个组件的队列更新状态(pending)被置为true,意思是现在正在更新。当执行componentDidMount的时候,由于setTimeout是异步的,就优先执行同步代码,两个setState被执行,但是由于当前处于pending状态,新的state会放到队列中,更新state的操作被延迟,因为这里为了防止多次setState导致的重复更新(合并setState)。一直到componentDidMount里面所有代码执行完,才将pending状态置为false,这个时候state才做了更新,所以前两次打印的state都是0。
当所有同步任务执行结束后,就开始执行setTimeout里面的代码,由于现在pending状态已经被设为false,所以每次setState就会立即执行,以至于这个时候打印出来的是2、3。
所以我说了那么多,和await有啥关系呢?
关键就在于这个Promise.resolve().then,then方法实际上是个异步执行的函数,在这里和setTimeout的作用一样,导致了看起来就像await对setState起效了,其实起效是因为异步操作。

呆头 2022-09-13 11:49:52

屏幕快照 2022-01-19 下午8.23.05.png

屏幕快照 2022-01-19 下午8.23.22.png

屏幕快照 2022-01-19 下午8.23.48.png

举个简单的例子: test-02 中的 await this.setState({ a: 10 }); 其实和 test-03 中的 this.setState({ a: 10 }); await undefined; 等价; 而 await undefined; 回导致其后面的代码会在下一个事件循环中才执行。

这就造成了 await 会对 react setState 起作用的假象。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文