首页 > 解决方案 > React 如何使用 setTimeout 处理递归 API 调用

问题描述

我正在进行 API 调用,如果失败,我需要在设定的时间后再次调用 API,但是,由于超时范围,我无法清除超时。

这是有效的,但可以清除超时:

React.useEffect(() => {
if (progress === 45 && !apiCallFailedRef.current) {
  callApi();
}

function callApi(){
    let requestData = {
      method: 'GET',
      path,
    };

    $.ajax(testPath, {
      method: 'GET',
      data: { data: JSON.stringify(requestData) },
    })
      .done(response => {
        // setLoading(false);
      })
      .fail(response => {
        console.log('failed')
        apiCallFailedRef.current = true;
        setTimeout(() => callApi(), 28000);
      });
  }
};

// How would I clear the timeout correctly?
// return () => {
//   clearTimeout();
// };
}, [progress])

标签: reactjsreact-hooks

解决方案


我建议不要永远重试,您可以使用特定的重试次数,并且每次重试也可以等待更长的时间再重试。

这将进行 api 调用,最多重试 5 次

function callApiWithRetry(url, options = {}, numRetries = 5, backoff = 250) {

    return fetch(url, options)
      .then(res => {

        // if successful, return JSON response
        if (res.ok) {
          return res.json();
        }
        
        // not successful, retry until numRetry is 0
        if (numRetries > 0) {
          // make the api call again, but reduce the retry count, and double the backoff time
          setTimeout(() => {
            return callApiWithRetry(url, options, numRetries - 1, backoff * 2)
          }, backoff);
        } else {
          // out of retries, something is wrong
          throw new Error(res);
        }
      })
      .catch(console.error);
}

推荐阅读