Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

axios封装(二)-队列管理 #6

Open
some-code opened this issue Jun 4, 2018 · 0 comments
Open

axios封装(二)-队列管理 #6

some-code opened this issue Jun 4, 2018 · 0 comments
Labels

Comments

@some-code
Copy link
Owner

在某些特定的场景(比如 即时搜索表格分页),会频繁的发起ajax请求,而由于ajax是异步API,所以返回的时序并不能够保证,这时候就需要实现一个ajax队列,在相同的请求发起时,取消处理上一个请求。

在使用 jquery.ajax 时,可以比较方便的使用 abort 方式中断处理ajax返回值,但是由于 axios 是依赖于 promise 的,导致了只能通过转换为 Promsie.reject 的方式中断处理。具体的代码如下:

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,
}

队列应用

队列一般结合函数防抖使用,在尽量减少请求次数的情况下,避免返回值顺序的错误

$(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);
    };
}
@some-code some-code added the http label Jun 6, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant