猿问

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

是否可以使用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();

}

显然,这是伪代码,但是您可以理解。


牧羊人nacy
浏览 261回答 3
3回答

泛舟湖上清波郎朗

限制axios请求本身很容易。真正令人头疼的是如何处理从无效请求返回的承诺。在处理从无效的axios请求返回的承诺时,什么被认为是理智的行为?他们应该永远待命吗?对于此问题,我看不到任何完美的解决方案。但是后来我得出了一种作弊的解决方案:如果我们不限制axios调用,而是限制实际的XMLHttpRequest怎么办?这使事情变得更容易,因为它避免了promise问题,并且更易于实现。想法是为最近的请求实现缓存,如果新请求与最近的请求匹配,则只需从缓存中提取结果,然后跳过XMLHttpRequest。由于axios拦截器的工作方式,以下代码段可用于有条件地跳过某些XHR调用:// This should be the *last* request interceptor to addaxios.interceptors.request.use(function (config) {&nbsp; /* check the cache, if hit, then intentionally throw&nbsp; &nbsp;* this will cause the XHR call to be skipped&nbsp; &nbsp;* but the error is still handled by response interceptor&nbsp; &nbsp;* we can then recover from error to the cached response&nbsp; &nbsp;**/&nbsp;&nbsp; if (requestCache.isCached(config)) {&nbsp; &nbsp; const skipXHRError = new Error('skip')&nbsp; &nbsp; skipXHRError.isSkipXHR = true&nbsp; &nbsp; skipXHRError.request = config&nbsp; &nbsp; throw skipXHRError&nbsp; } else {&nbsp; &nbsp; /* if not cached yet&nbsp; &nbsp; &nbsp;* check if request should be throttled&nbsp; &nbsp; &nbsp;* then open up the cache to wait for a response&nbsp; &nbsp; &nbsp;**/&nbsp; &nbsp; if (requestCache.shouldThrottle(config)) {&nbsp; &nbsp; &nbsp; requestCache.waitForResponse(config)&nbsp; &nbsp; }&nbsp; &nbsp; return config;&nbsp; }});// This should be the *first* response interceptor to addaxios.interceptors.response.use(function (response) {&nbsp; requestCache.setCachedResponse(response.config, response)&nbsp; return response;}, function (error) {&nbsp; /* recover from error back to normality&nbsp; &nbsp;* but this time we use an cached response result&nbsp; &nbsp;**/&nbsp; if (error.isSkipXHR) {&nbsp; &nbsp; return requestCache.getCachedResponse(error.request)&nbsp; }&nbsp; return Promise.reject(error);});

慕运维8079593

也许您可以尝试使用axios提供的“取消”功能。使用它,您可以确保在挂起状态中没有任何两个(或更多,取决于实现)类似的请求。在下面,您将找到一个简化的小示例,该示例演示如何确保仅处理最新的请求。您可以对其进行一些调整以使其像请求池一样起作用&nbsp; &nbsp; import axios, { CancelToken } from 'axios';&nbsp; &nbsp; const pendingRequests = {};&nbsp; &nbsp; const makeCancellable = (headers, requestId) => {&nbsp; &nbsp; &nbsp; if (!requestId) {&nbsp; &nbsp; &nbsp; &nbsp; return headers;&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; if (pendingRequests[requestId]) {&nbsp; &nbsp; &nbsp; &nbsp; // cancel an existing request&nbsp; &nbsp; &nbsp; &nbsp; pendingRequests[requestId].cancel();&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; const source = CancelToken.source();&nbsp; &nbsp; &nbsp; const newHeaders = {&nbsp; &nbsp; &nbsp; &nbsp; ...headers,&nbsp; &nbsp; &nbsp; &nbsp; cancelToken: source.token&nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; pendingRequests[requestId] = source;&nbsp; &nbsp; &nbsp; return newHeaders;&nbsp; &nbsp; };&nbsp; &nbsp; const request = ({&nbsp; &nbsp; &nbsp; url,&nbsp; &nbsp; &nbsp; method = 'GET',&nbsp; &nbsp; &nbsp; headers,&nbsp; &nbsp; &nbsp; id&nbsp; &nbsp; }) => {&nbsp; &nbsp; &nbsp; const requestConfig = {&nbsp; &nbsp; &nbsp; &nbsp; url,&nbsp; &nbsp; &nbsp; &nbsp; method,&nbsp; &nbsp; &nbsp; &nbsp; headers: makeCancellable(headers || {}, id)&nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; return axios.request(requestConfig)&nbsp; &nbsp; &nbsp; &nbsp; .then((res) => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; delete pendingRequests[id];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return ({ data: res.data });&nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp; &nbsp; .catch((error) => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; delete pendingRequests[id];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (axios.isCancel(error)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;console.log(`A request to url ${url} was cancelled`); // cancelled&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return handleReject(error);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; };&nbsp; &nbsp; export default request;
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答