如何解决请求异步的竞态问题?

如何解决请求异步的竞态问题?

请添加图片描述

1、交互层面解决

  ①、添加全局loading遮罩
  ②、禁用操作按钮

缺点:

  ①、阻碍交互
  ②、触发操作的动作多样,不太好管控

2、取消请求

定义:在每一次请求的时候,取消上一次请求。

2.1、axios的cancellation

let CancelToken=axios.CancelToken()
let source;

/**
提交表单
*/
function submit(params){
  	if(source){
      	source.cancel("取消请求)
    }
  	source=CancelToken.source()
    return axios.post('/test',{params}
    ,{
    	cancelToken:source.token
    }).then((respense)=>{
      //请求成功处理逻辑
    }).catch((thrown)=>{
        //区别取消请求和请求失败处理
        if(axios.isCancel(thrown){
            //取消请求操作逻辑
        }else{
          	//请求错误操作逻辑
        }	
    })
}

2.2、可取消的Promise

注:promise本身是不能取消的,可以通过手动把Promise设置为rejected状态

let doCancel;

function submit(params){
  if(doCancel){
    // 设置上一次的 Promise 设为 rejected 状态
     doCancel("请求取消")
  }
	return new Promise((resolve,reject)=>{
   	//挂载reject方法  
    doCancel=reject
      let xhr=new XMLHttpRequest();
      xhr.on("load",resolve);
    	xhr.on("error",reject);
      xhr.open("POST","/test",true)

     // 发送请求条件,这里未作处理
      xhr.send(null)
  }).catch((thrown)=>{
      // 区别处理取消请求和请求错误
    if (axios.isCancel(thrown)) {
      // 取消请求的逻辑
    } else {
      // 请求错误
    }
  })
}

2.3、RxJs的switchMap 操作符

switchMap 有点类似于Promise。新的数据派发会取消上一次的数据。

var btn = document.querySelector('.js-query');
var inputStream = Rx.Observable.fromEvent(btn, 'click')
  .debounceTime(250) // 防抖,防止请求过于频繁
  .switchMap(url => Http.get(url)) 
  .subscribe(data => render(data));

3、抛弃无用的请求

最后一种处理方式最为比较容易理解:只处理当前查询条件对应请求结果,其它的查询条件的结果我们都认为是无用的请求,对于无用的请求我们在回调函数里不处理就可以了。

// 请求标记
let gobalReqID = 0

// 请求的函数
funtion query (keyword) {
  gobalReqID++
    let curReqID = gobalReqID
    return axios.post('/list', {
    keyword
  }).then(res => {
    // 对比闭包内的 curReqID 是否和 gobalReqID 一致
    if (gobalReqID === curReqID) {
        return res
    } else {
        return Promse.reject('无用的请求')
    }
  })
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值