专栏首页贾鹏辉的技术专栏@CrazyCodeBoyReact Native 性能优化之可取消的异步操作

React Native 性能优化之可取消的异步操作

React Native 性能优化之可取消的异步操作

本文出自《React Native 研究与实践》系列文章。

概述

在项目开发中离不了的需要进行一些异步操作,这些异步操作在改善用户体验的同时也带来了一些性能隐患。 比如,在某页面进行异步操作,异步操作还没有完成时,该页面已经关闭,这时由于异步操作的存在,导致系统无法及时的回收资源,从而导致性能的降低,甚至出现oom。

总而言之,异步操作在改善用户体验,增强系统灵活性的同时也带来了一些性能隐患,如果使用不当则会带来一些副作用。

那么如何在使用异步操作的同时规避它所带来的副作用呢?

问题不是出在异步操作上,异步操作本没有错,错在异步操作的不合理使用上。比如,页面已经关闭了,而页面的异步操作还在进行等使用问题。 所以我们需要在编程中学会“舍得”,在适当的时候去取消一些异步操作。

为Promise插上可取消的翅膀

Promise是React Native开发过程中用于异步操作的最常用的API,但Promise没有提供用于取消异步操作的方法。为了实现可取消的异步操作,我们可以为Promise包裹一层可取消的外衣。

const makeCancelable = (promise) => {
  let hasCanceled_ = false;
  const wrappedPromise = new Promise((resolve, reject) => {
    promise.then((val) =>
      hasCanceled_ ? reject({isCanceled: true}) : resolve(val)
    );
    promise.catch((error) =>
      hasCanceled_ ? reject({isCanceled: true}) : reject(error)
    );
  });
  return {
    promise: wrappedPromise,
    cancel() {
      hasCanceled_ = true;
    },
  };
};  

然后可以这样使用取消操作:

const somePromise = new Promise(r => setTimeout(r, 1000));//创建一个异步操作
const cancelable = makeCancelable(somePromise);//为异步操作添加可取消的功能
cancelable
  .promise
  .then(() => console.log('resolved'))
  .catch(({isCanceled, ...error}) => console.log('isCanceled', isCanceled));
// 取消异步操作
cancelable.cancel();   

上述方法,可以为异步操作添加可取消的功能,但是使用还是不够方便:在每个使用makeCancelable的页面都需要复制粘贴上述代码。 下面我们做一下改进,将上述代码抽离到一个文件中。

 /*
 * Cancelable
 * GitHub:https://github.com/crazycodeboy
 * Eamil:crazycodeboy@gmail.com 
 * @flow
 */
'use strict'
export default function makeCancelable(promise){
    let hasCanceled_ = false;
    const wrappedPromise = new Promise((resolve, reject) => {
        promise.then((val) =>
            hasCanceled_ ? reject({isCanceled: true}) : resolve(val)
        );
        promise.catch((error) =>
            hasCanceled_ ? reject({isCanceled: true}) : reject(error)
        );
    });
    return {
        promise: wrappedPromise,
        cancel() {
            hasCanceled_ = true;
        },
    };
}

这样在使用的时候只需要将makeCancelable导入到你的相应js文件中就可以了。

import makeCancelable from '../util/Cancelable'

可取消的网络请求fetch

fetch是React Native开发过程中最常用的网络请求API,和Promis一样,fetch也没有提供用于取消已发出的网络请求的API。因为fetch返回的是一个Promise,所以我们可以借助上述方法,来取消fetch所发出的网络请求。

this.cancelable = makeCancelable(fetch('url')));
        this.cancelable.promise
            .then((response)=>response.json())
            .then((responseData)=> {          
                console.log(responseData);                            
            }).catch((error)=> {
                console.log(error); 
            });

取消网络请求:

this.cancelable.cancel();

在项目中的使用

为了提高React Native应用的性能,我们需要在组件卸载的时候不仅要主动释放掉所持有的资源,也要取消所发出的一些异步请求操作。

componentWillUnmount() {      
  this.cancelable.cancel();
}

About

本文出自[《React Native 研究与实践》栏目。

这里有你需要的干货:

微博:第一时间获取推送 个人博客:你需要的,才是干货 GitHub:我的开源项目

推荐阅读

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 带你快速掌握Flutter的视图(Widgets)

    在这篇文章中,将向大家分享Flutter开发中的一些视图(Widgets)相关的一些知识和经验,主要包含:

    CrazyCodeBoy
  • React Native列表之FlatList开发实用教程

    在APP开发过程中,列表可谓是页面最重要的一种展现形式了,几乎每一个APP都离不了列表,那么在这篇文章中将向大家分享在React Native中该如何实现列表,...

    CrazyCodeBoy
  • Flutter Hero动画开发实用教程

    在这篇文章中,将向大家分享Flutter动画中的重要一员Hero动画,以及一些Hero动画的开发技巧和经验。

    CrazyCodeBoy
  • 基于注解@Async的SpringBoot异步调用及使用场景

    首先要在springboot项目的启动上添加@EnableAsync开启异步监控,自动扫描。没有这个主角儿一切都是扯淡。

    用户1956326
  • 分布式系统关注点(19)——深入浅出「异步」

    Z哥在前面的三篇文章里和你一起聊了「高性能」主题下与「缓存」相关的内容。这次和你来聊聊提高性能的另一个大招——「异步」。

    Zachary_ZF
  • 聊聊“异步”

    在我们编程的时候,经常会遇到一个概念——异步,诸如异步通信,异步线程,异步代码,异步调用,异步编程等等,那么

    半吊子全栈工匠
  • 当我们做后仿时我们究竟在仿些什么(三)

    最近又做了一些后仿debug的工作,有两点是之前两篇没有提到太多的,趁假期有点时间记录下来。标题也照旧,加个三吧。

    icsoc
  • python 按钮的响应事件

    在PyCharm中创建一个项目,然后点击“Tools”--“External Tools”--“QTDesinger”打开QT Desinger

    py3study
  • 盘点2017十大科学突破,让孩子与未来相遇

    站在年尾,2017犹如白驹过隙 一年的光阴也只是人类历史间短短一瞬 我们感叹时光的飞逝 科技却让未来向我们靠近 让我们带孩子与科技遇见 一起看看 2017十大科...

    企鹅号小编
  • 一个简单的node爬虫踩坑之路

    一个简单的node爬虫踩坑之路准备工作 最近在看爬虫相关的文章,偶然想起来尝试一下用node来实现一个简单的爬虫。但是爬别的多没意思,当然是爬美女图片啊。。。 ...

    企鹅号小编

扫码关注云+社区

领取腾讯云代金券