为了账号安全,请及时绑定邮箱和手机立即绑定

如何避免在axios中发送多个重复的AJAX请求

如何避免在axios中发送多个重复的AJAX请求

牧羊人nacy 2021-04-29 10:11:40
是否可以使用axios自动限制所有发往特定端点列表的请求?也许使用axios拦截器?当前,我限制发送axios请求的用户操作,但是问题在于,我必须在有导致某些AJAX请求的用户操作的地方写这个。像这样  const throttledDismissNotification = throttle(dismissNotification, 1000)  const dismiss = (event: any) => {    throttledDismissNotification();  };  render() {    return (      <Button onClick={dismiss}>Dismiss Notification</Button>    )  }这导致很多混乱,我想知道这是否可以自动化。就像是:if(request.url in listOfEndpointsToThrottle && request.params in cacheOfPreviousRequestsToThisEndpoint) {  StopRequest();}显然,这是伪代码,但是您可以理解。
查看完整描述

3 回答

?
泛舟湖上清波郎朗

TA贡献1818条经验 获得超3个赞

限制axios请求本身很容易。真正令人头疼的是如何处理从无效请求返回的承诺。在处理从无效的axios请求返回的承诺时,什么被认为是理智的行为?他们应该永远待命吗?


对于此问题,我看不到任何完美的解决方案。但是后来我得出了一种作弊的解决方案:


如果我们不限制axios调用,而是限制实际的XMLHttpRequest怎么办?


这使事情变得更容易,因为它避免了promise问题,并且更易于实现。想法是为最近的请求实现缓存,如果新请求与最近的请求匹配,则只需从缓存中提取结果,然后跳过XMLHttpRequest。


由于axios拦截器的工作方式,以下代码段可用于有条件地跳过某些XHR调用:


// This should be the *last* request interceptor to add

axios.interceptors.request.use(function (config) {

  /* check the cache, if hit, then intentionally throw

   * this will cause the XHR call to be skipped

   * but the error is still handled by response interceptor

   * we can then recover from error to the cached response

   **/ 

  if (requestCache.isCached(config)) {

    const skipXHRError = new Error('skip')

    skipXHRError.isSkipXHR = true

    skipXHRError.request = config

    throw skipXHRError

  } else {

    /* if not cached yet

     * check if request should be throttled

     * then open up the cache to wait for a response

     **/

    if (requestCache.shouldThrottle(config)) {

      requestCache.waitForResponse(config)

    }

    return config;

  }

});


// This should be the *first* response interceptor to add

axios.interceptors.response.use(function (response) {

  requestCache.setCachedResponse(response.config, response)

  return response;

}, function (error) {

  /* recover from error back to normality

   * but this time we use an cached response result

   **/

  if (error.isSkipXHR) {

    return requestCache.getCachedResponse(error.request)

  }

  return Promise.reject(error);

});


查看完整回答
反对 回复 2021-05-13
?
慕运维8079593

TA贡献1876条经验 获得超5个赞

也许您可以尝试使用axios提供的“取消”功能。


使用它,您可以确保在挂起状态中没有任何两个(或更多,取决于实现)类似的请求。


在下面,您将找到一个简化的小示例,该示例演示如何确保仅处理最新的请求。您可以对其进行一些调整以使其像请求池一样起作用


    import axios, { CancelToken } from 'axios';


    const pendingRequests = {};


    const makeCancellable = (headers, requestId) => {

      if (!requestId) {

        return headers;

      }


      if (pendingRequests[requestId]) {

        // cancel an existing request

        pendingRequests[requestId].cancel();

      }

      const source = CancelToken.source();

      const newHeaders = {

        ...headers,

        cancelToken: source.token

      };

      pendingRequests[requestId] = source;

      return newHeaders;

    };


    const request = ({

      url,

      method = 'GET',

      headers,

      id

    }) => {

      const requestConfig = {

        url,

        method,

        headers: makeCancellable(headers || {}, id)

      };


      return axios.request(requestConfig)

        .then((res) => {

          delete pendingRequests[id];

          return ({ data: res.data });

        })

        .catch((error) => {

          delete pendingRequests[id];

          if (axios.isCancel(error)) {

             console.log(`A request to url ${url} was cancelled`); // cancelled

          } else {

             return handleReject(error);

          }

        });

    };


    export default request;


查看完整回答
反对 回复 2021-05-13
  • 3 回答
  • 0 关注
  • 260 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信