高频请求下取消前一次请求

      发布在:前端技术      评论:3 条评论

先讲下需求,在一个 input 框里我们每输入东西都去后端检索,正常的做法是把请求包在防抖里,来减少请求,但这样还是很有概率导致用户输入的东西无效,其次是很有可能我上一次的请求会在下一次请求之后才返回,如果不加顺序锁会导致数据展示错乱。看到百度搜索框的响应后发现他们是下一次请求的时候把之前的请求直接 canceled掉,这样做的好处是用户方面不会有任何感官,而且展示的数据不会错乱。

XMLHttpRequest

在原生 ajax 中提供了一个abort()方法来取消请求

var xhr = new XMLHttpRequest(),
    method = "GET",
    url = "";
xhr.open(method,url,true);
xhr.send();
// 在取消的时候调用这条 即可取消请求
xhr.abort();
jQuery

jQuery 的 ajax 也与原生基本无出入,方法更加简单

var xhr;
var ajax = function () {
    if (xhr && xhr.readyState != 4) {
        xhr.abort();
    }
    xhr = $.ajax({
        url: '',
        success: function (data) {
            //do success
         }
     });
 };
 //轮询请求,,如果上一次请求未完成,则取消上次请求
 setInterval(ajax, 2000);
axios

axios 中提供一个 CancelToken 的方法 会返回一个钩子函数,把他赋值给你的一个公共方法即可

import { CancelToken } from 'axios';
// 一个相应 input 输入的方法
keywordChange(e: any){
    const _this = this;
    // 全局作用域中有一个 cancelRequest 与下方 CancelToken 关联
    this.cancelRequest();
    // axios 已经被挂载到this 上了 可以直接调用
    this.axios({
        cancelToken: new CancelToken(function executor(c) {
            _this.cancelRequest = c;
        }),
        url: '',
        method: 'GET',
    }).then((result) => {
        console.log(result);
    })
},
Responses
    加载中...
  1. 牛皮牛皮

    回复
  2. 最优的解法应该是直接用一个 debounce,输入中不发请求就可以

    回复
    • Hansuku博主

      需要实时给到用户搜索提示的情况下,取消可能才是最优解,毕竟这个已经在百度这个每日亿级流量的搜索入口验证过了。

      回复