前几天面试web前端工作,被一道题问蒙了,面试官问React中setState的异步更新如何控制为同步更新,当时懵的一批,毕竟面的第一家前端,心里感觉本来就是异步,怎么会改成同步,这不扯呢吗,事后才发现这件事无非就是一个异步的协同问题,平时看了很多关于es6的Promise,async/await的语法,到关键时候还是没用上,究其原因还是平时代码用的少。下面针对这个问题再复习一遍es6的知识。
1.首先说一下Promise对象,Promise即为承诺的意思,初始化Promise对象会传入一个函数,此函数两个参数分别是resolve和reject,resolve代表成功,reject代表失败。详细的请看阮一峰的es6相关知识,讲的很详细。
var promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
然后再顺便讲一下async/await的用法,主要就是使得异步操作变得更加简单,async代表异步,await会返回一个Promise对象,可以说使得异步变成同步。同样,详细的可以查看阮一峰的es6。
async function f() {
await test();//hellow
}
function test(){
return 'hellow';
}
下面开始进入主题,其实懂得上面的两个语法,就没什么难的。
async componentDidMount(){
await this.setStateAsync([{key:0,id:0,name:'sa',code:'44',width:'44',height:'44'}]);
console.log('action');
}
setStateAsync(state){
return new Promise((resolve => {
console.log('1');
this.setState({dataSource:state},resolve(1));
}))
}
因为setState是异步的,所以放在返回的Promise对象中,然后更新完后之后调用resolve,在componentDidMount中await就可以了,这样就保证了更新界面的同步性。
2.其实在在利用setState进行更新时,会有一个更新队列,我们的更新其实并不是真正的异步处理,而是更新的时候把更新内容放到了更新队列中,最后批次更新,这样才表现出异步更新的状态。其实也可以打破这种状态:
(1)利用原生js绑定事件更新state
(2)利用setTimeout更新state