在某些特定的场景(好比 即时搜索
,表格分页
),会频繁的发起ajax请求,而因为ajax是异步API,因此返回的时序并不可以保证,这时候就须要实现一个ajax队列,在相同的请求发起时,取消处理上一个请求。javascript
在使用 jquery.ajax
时,能够比较方便的使用 abort
方式中断处理ajax返回值,可是因为 axios
是依赖于 promise
的,致使了只能经过转换为 Promsie.reject
的方式中断处理。具体的代码以下:java
import axios from 'axios'; import Qs from 'qs'; // 上一篇文章中定义的错误处理文件 import httpErrorHandler from './httpErrorHandler'; const instance = axios.create(); // 请求队列 const queue = []; // axios内置的中断ajax的方法 const cancelToken = axios.CancelToken; // 拼接请求的url和方法,一样的url+方法能够视为相同的请求 const token = (config) =>{ return `${config.url}_${config.method}` } // 中断重复的请求,并从队列中移除 const removeQueue = (config) => { for(let i=0, size = queue.length; i < size; i++){ const task = queue[i]; if(task.token === token(config)) { task.cancel(); queue.splice(i, 1); } } } //添加请求拦截器 instance.interceptors.request.use(config=>{ removeQueue(config); // 中断以前的同名请求 // 添加cancelToken config.cancelToken = new cancelToken((c)=>{ queue.push({ token: token(config), cancel: c }); }); return config; }, error => { return Promise.reject(error); }); //添加响应拦截器 instance.interceptors.response.use(response=>{ // 在请求完成后,自动移出队列 removeQueue(response.config); return response.data }, httpErrorHandler); /** * 封装后的ajax post方法 * * @param {string} url 请求路径 * @param {object} data 请求参数 * @param {object} config 用户自定义设置 * @returns */ function post (url, data, config = {}) => { return instance.post(url, data, config) } /** * 封装后的ajax get方法 * * @param {string} url 请求路径 * @param {object} params 请求参数 * @param {object} config 用户自定义设置 * @returns */ function post (url, params, config = {}) => { return instance.get(url, {params}, config) } export default { post, get, }
队列通常结合函数防抖使用,在尽可能减小请求次数的状况下,避免返回值顺序的错误jquery
$(input).on('input', evt => { // 在用户不断的输入过程当中,当暂停输入100ms才发起ajax,在发起ajax的同时,中断上一个查询keyword的ajax debounce(()=>{ get('http://baidu.com', {keyword: evt.target.value}) }) }) // 定义一个防抖函数 function debounce(fn, step = 100) { let timeout = null; return function () { clearTimeout(timeout); timeout = setTimeout(() => { fn.apply(this, arguments); }, step); }; }