您的位置:首页 > 其它

从合并请求角度谈性能优化

2020-04-30 16:02 281 查看
### 从合并请求角度谈性能优化   性能优化是前端非常重要的一块,可下手的地方有很多,比如图片层次、JS层次、webpack工程层次、CSS层次、CDN层次等等,其中关于请求的优化是整个项目运行中非常重要的一块,所以这次我们来讲一下请求优化的一个小方法。 ##### 来看需求   最近在一个React项目中有看见一个类似结构的代码,其中reqData、reqListData、reqProData是三个函数,内部分别有三个不同的Promise请求,请求获得数据后,将数据保存至this.state中。 ```js componentDidMount() { this.reqData(); this.reqListData(); this.reqProData(); } /** * 第一个请求 **/ reqData() { ajax.getData().then(res => { // do something with this.setState({}) }) } /** * 第二个请求 **/ reqListData() { ajax.getListData().then(res => { // do something with this.setState({}) }) } /** * 第三个请求 **/ reqProData() { ajax.getProData().then(res => { // do something with this.setState({}) }) } ```   事实上,这段代码是没有问题的,毕竟在这个需求中,这三个返回的数据都是互不干扰互不联系的,但是在我们开发的过程中,我们需要有想到可能日后在每个地方都会有变动的地方,假如在后续开发中,我们在第二个请求的时候,需要根据第一个请求返回的数据进行判断再插入this.state中呢?这是一个非常有可能性的需求。   而且值得注意的是,这是一个React项目,使用this.setState的时候,会触发render方法重新渲染你的界面(这里不考虑其他的,如shouldComponentUpdate等情况),那么这样来构建代码,会产生非常多次的无必要的render,严重影响性能。   那么我们的需求就很清晰了,我们需要将多次的render缩减为一次,并使得请求返回的数据能够互相有业务逻辑来往,所以在这里,我们选择使用Promise.all ##### Promise.all   Promise.all大家应该不陌生,作为ES6中作为Promise的伴生静态方法,他有一个显著功效:**将多个Promise对象实例包装,生成并返回一个新的Promise实例。**   使用这个方法,你可以将多个的Promise以数组参数的形式传入,当所有Promise实例全部(**注意是全部**)变为resolve后,该方法才会返回,并可在then方法中获得一个数组形式的结果,你可以使用数组解构的方法轻松获取这些参数 ```js // 使用方法 Promise.all([p1, p2, p3]).then(function (results) { let [res1, res2, res3] = results; }); ```   下面的是博主给大家写的示例,让大家简单的了解一下这个Promise.all的使用方法。 ```js // 示例 let promise1 = new Promise(function (resolve, reject) { if (true) { resolve(1); } else { reject(false); } }); let promise2 = new Promise(function (resolve, reject) { if (true) { resolve(2); } else { reject(false); } }); let promise3 = new Promise(function (resolve, reject) { if (true) { resolve(3); } else { reject(false); } }); Promise.all([promise1, promise2, promise3]).then(function (results) { let [res1, res2, res3] = results; console.log(res1); console.log(res2); console.log(res3); if (res2 === 2) { console.log(res3 * 3); } // do something with this.setState({}) }); ``` ##### 解决   OK那么接下来方向就很明确了,于是我将componentDidMount中的代码修改成了以下的结构。 ```js componentDidMount() { // ajax此处的ajax只是自己的封装,实际上ajax.reqData()等参数还是 Promise 格式 Promise.all([ajax.getData(), ajax.getListData(), ajax.getProData()]).then((results) => { const [res1, res2, res3] = results; // 将结果作为参数传入,根据内部逻辑返回需要setState的数据 const { data } = this.reqDataFormat(res1); const { list } = this.reqListDataFormat(res2); const { pro } = this.reqProDataFormat(res3); if (list) { // pro = list.res; // Do something with side effects } this.setState({ data, list, pro }) }); } ```   合并请求后根据测试,耗时不增反而略有下降,可读性上升,减少三次rander,性能提高。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: