【问题标题】:How to stop polling using timeout in fetch request while adding intervals添加间隔时如何在获取请求中使用超时停止轮询
【发布时间】:2022-01-11 04:09:13
【问题描述】:

我正在轮询我的报告,在每个请求之间添加 5 秒的间隔。

const addDelay = timeout => new Promise(resolve => setTimeout(resolve, timeout))

export const myReport = () => async (dispatch) => {
  dispatch({
    type: constants.DOWNLOAD_REPORT_REQUEST
  })

  let url = `/admin/dashboard/report.js?project_id=${projectId}&tool_id=${toolId}`

  try {
    const subscribe = async (uri) => {
      let response = await fetch(uri, {
        method: 'GET',
        headers: {
          'content-type': 'application/json',
          'x-api-token': `Bearer ${token}`
        }
      })
      const resBody = await response.json()
      if (resBody.status === 'success') {
        window.location.href = resBody.url
        dispatch({
          type: constants.DOWNLOAD_REPORT_SUCCESS
        })
      } else {
        await addDelay(5000)
        await subscribe(url)
        //   return;
        // setTimeout(() => {
        //   dispatch({
        //     type: constants.SHOW_DOWNLOAD_POPUP
        //   })
        //   return;
        // }, 15000);
      }
    }
    subscribe(url)
  } catch (error) {
    dispatch({
      type: constants.DOWNLOAD_REPORT_FAILURE,
      errorMessage: error.status
    })
  }
}

现在,我想在 15 秒后停止轮询并显示一个弹出窗口。

问题是我无法在此处添加 setTimeout,因为我使用的是async。而且它不会一次又一次地停止调用subscribe 方法,因为它不断进入其他部分,return 不起作用。

我想退出其他部分,停止调用该函数并在 15 秒后显示弹出窗口。我如何做到这一点?

【问题讨论】:

    标签: javascript long-polling ajax-polling


    【解决方案1】:

    你的 return 语句不可能工作,因为这个函数是 recursive - 如果 fetch 一直失败,它永远不会到达那里。添加一个索引来跟踪您重试订阅的次数怎么样?

    const addDelay = (timeout) =>
      new Promise((resolve) => setTimeout(resolve, timeout));
    
    const failed = 0;
    
    export const myReport = () => async (dispatch) => {
      dispatch({
        type: constants.DOWNLOAD_REPORT_REQUEST,
      });
    
      let url = `/admin/dashboard/report.js?project_id=${projectId}&tool_id=${toolId}`;
    
      try {
        const subscribe = async (uri) => {
          let response = await fetch(uri, {
            method: 'GET',
            headers: {
              'content-type': 'application/json',
              'x-api-token': `Bearer ${token}`,
            },
          });
          const resBody = await response.json();
          if (resBody.status === 'success') {
            window.location.href = resBody.url;
            dispatch({ type: constants.DOWNLOAD_REPORT_SUCCESS });
          } else {
            if (failed >= 3) {
              // whatever you want to do on fail
            } else {
              failed += 1;
              await addDelay(5000);
              await subscribe(url);
            }
          }
        };
        subscribe(url);
      } catch (error) {
        dispatch({
          type: constants.DOWNLOAD_REPORT_FAILURE,
          errorMessage: error.status,
        });
      }
    };
    
    

    【讨论】:

      【解决方案2】:

      您可以跟踪自轮询开始以来经过的时间量,并在达到零时退出。

      const addDelay = timeout => new Promise(resolve => setTimeout(resolve, timeout))
      
      export const myReport = () => async (dispatch) => {
        dispatch({
          type: constants.DOWNLOAD_REPORT_REQUEST
        })
      
        let url = `/admin/dashboard/report.js?project_id=${projectId}&tool_id=${toolId}`
      
        let remainingPollingTime = 15000 // <--------
        try {
          const subscribe = async (uri) => {
            let response = await fetch(uri, {
              method: 'GET',
              headers: {
                'content-type': 'application/json',
                'x-api-token': `Bearer ${token}`
              }
            })
            const resBody = await response.json()
            if (resBody.status === 'success') {
              window.location.href = resBody.url
              dispatch({
                type: constants.DOWNLOAD_REPORT_SUCCESS
              })
            } else {
              if(remainingPollingTime <= 0) { // <--------
                dispatch({
                  type: constants.SHOW_DOWNLOAD_POPUP
                })
                return
              }
      
              remainingPollingTime -= 5000 // <--------
              await addDelay(5000)
              await subscribe(url) 
            }
          }
          subscribe(url)
        } catch (error) {
          dispatch({
            type: constants.DOWNLOAD_REPORT_FAILURE,
            errorMessage: error.status
          })
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-21
        • 2021-10-13
        相关资源
        最近更新 更多