美文网首页React Native开发React Native开发经验集
React/React-Native组件卸载取消异步请求

React/React-Native组件卸载取消异步请求

作者: GL101 | 来源:发表于2019-12-10 15:26 被阅读0次

    某些时候当一个组件卸载时,网络请求还在进行中,有些请求不处理没有问题,但有些不处理会带来一些问题。轻微的问题比如警告,严重的会引起App崩溃。在组件被卸载时,取消一些网络请求还是很有必要的。这种问题处理方式大概有四种:

    1.在组件中添加一个标志,在网络请求的回调中进行判断。

    constructor(){
      this.unmout = false;
    }
    
    componentDidMount(){
      this._httpServoce.getXXX().then(value=>{
        if(this.unmount){
          return;
        }
        this.setState({data:value});
      })
    }
    
    componentWillUnmount(){
      this.unmout = true;
    }
    

    2.手动实现取消
    底层实现一个取消方法,当将fetch的返回执(promise),进行一次封装。

    function cancelable(response) {
        this.cancel = false;
        const data = new Promise((resolve,rejected)=>{
            response.then(value=>this.cancel?rejected("cancel"):resolve(value) ).catch(err=>this.cancel?rejected("cancel"):rejected(err));
        });
    
        return {
            data,
            cancel:()=>{this.cancel = true;}
        }
    }
    
    cons response = fetch({....});
    const {data,cancel} = cancelable( promise1);
    data.then(value=>console.log(value)).catch(error=>console.log(error));
    cancel();
    

    这里有人已经实现的一个hook可以拿来就用,比较方便。

    也可以用Promise.race实现,看这篇文章

    3.使用AbortController
    react-native 0.60之前的版本需要安装abortcontroller-polyfill
    只要发送请求时,传入信号量signal,当需要取消请求时调用controller上的abort方法。

    const controller = new AbortController();
    const signal = controller.signal;
    fetch('/some/url', {signal})
      .then(res => res.json())
      .then(data => {
        // do something with "data"
      }).catch(err => {
        if (err.name == 'AbortError') {
          return;
        }
      });
    // controller.abort(); // can be called at any time
    

    4.使用Axios库
    Axios 是一个基于promise 的HTTP 库,对请求和响应都做了很好的封装。
    使用Axios取消请求,首先创建一个source,然后将source.token传入请求方法的配置里。当需要取消的时候调用source的cancel方法。

    const CancelToken = axios.CancelToken;
    const source = CancelToken.source();
    
    axios.get('/user/12345', {
      cancelToken: source.token
    }).catch(function (thrown) {
      if (axios.isCancel(thrown)) {
        console.log('Request canceled', thrown.message);
      } else {
        // handle error
      }
    });
    
    axios.post('/user/12345', {
      name: 'new name'
    }, {
      cancelToken: source.token
    })
    
    // cancel the request (the message parameter is optional)
    source.cancel('Operation canceled by the user.');
    

    相关文章

      网友评论

        本文标题:React/React-Native组件卸载取消异步请求

        本文链接:https://www.haomeiwen.com/subject/qvcggctx.html