es7 async await 为什么会对react setState起作用?
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
答案有了。
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设计到底怎么样
await不仅能等待Promise,也可以等待任意表达式的结果,如异步函数的返回值等。
具体找了篇文章你哭看下。
理解 JavaScript 的 async/await
虽然是个老问题了,但还是忍不住回答一下。
实际上不是await对setState生效,而是async改变了handleChange这个方法,关于async/await做了什么,源码太麻烦了,我参考了简书上的一篇文章:JavaScript 的 async/await : async 和 await 在干什么
async函数最终会返回一个Promise,而await会等待后面的执行结束后用Promise.resolve包裹一下,将后面的代码包裹在then里面。
那么await为什么会对setState起效呢?我参考了一下react-lite(后面统称为react)的实现后豁然开朗。
react中调用setState的地方无疑只有两个,一个是生命周期钩子函数,一个是合成事件,两者情况基本上一致,以下图为例。
在执行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起效了,其实起效是因为异步操作。
举个简单的例子: test-02 中的
await this.setState({ a: 10 });
其实和 test-03 中的this.setState({ a: 10 }); await undefined;
等价; 而await undefined;
回导致其后面的代码会在下一个事件循环中才执行。这就造成了 await 会对 react setState 起作用的假象。