使用重试参数获取请求

时间:2018-04-06 17:29:28

标签: javascript fetch-api

我正在使用fetch API并尝试实现一个获取重试参数的函数,并在前一个请求失败时重新发送另一个请求。 我找到了this answer,这是我的代码,有人知道如何在非递归中编写函数吗?

const fetchRetry = (url, delay, limit, fetchOptions = {}) => {
    return new Promise((resolve, reject) => {
        const success = (response) => resolve(response);

        const failure = (error) => {
            if (limit) {
                setTimeout(fetchUrl, delay)
            }
            else {
                // this time it failed for real
                reject(error);
            }
            limit--;
        }

        const finalHandler = (finalError) => { throw finalError };

        const fetchUrl = () => {
            return fetch(url, fetchOptions)
                .then(success)
                .catch(failure)
                .catch(finalHandler);
        }

        fetchUrl();
    });
}

fetchRetry('https://jsonplaceholder.typicode.commmmmm/posts/1', 1000, 3)
    .then((response) => {
        if (!response.ok) {
            throw new Error('failed!');
        }
        return response;
    })
    .then((response) => console.log(response))
    .catch((error) => console.log(error));

1 个答案:

答案 0 :(得分:0)

这可以简单得多:

var fetchRetry = (url, delay, limit, fetchOptions = {}) => {
  const later = delay =>
    new Promise(resolve=>setTimeout(resolve,delay));
  const recur = (timesTried,err) =>
    (timesTried>=limit)
      ? Promise.reject(err)
      : fetch(url, fetchOptions)
        .catch(
          err=>
            later(delay).then(
              ()=>recur(timesTried+1,err)
            )
        );
  return recur(0);
}

不使用重复功能可能会使其更复杂。也许如果您使用async/await,您可以使用while循环并尝试/ catch

然而;任何递归通常都可以通过reduce来完成,反之亦然,但最好不要使用reduce进行大量的重试:



var fetch=()=>console.log("trying") || Promise.reject("no");

const fetchRetry = (url, delay, limit, fetchOptions = {}) => {
  const later = delay =>
    new Promise(resolve=>setTimeout(resolve,delay));
  const tries = Array.from(new Array(limit),(item,index)=>index+1);
  return tries.reduce(
    (promise,value)=>
      promise.catch(
        err=>
          (value===tries.length)
            ? Promise.reject(err)
            : later(delay).then(()=>fetch(url,fetchOptions))
      ),
    fetch(url,fetchOptions)
  );
}
console.log("starting...");
fetchRetry("",1000,2)
.catch(err=>console.warn("error:",err));