如何将 setTimeout 添加到使用 redux 的 fetch Promise?

IT技术 reactjs promise react-native redux fetch
2021-05-10 07:43:33

如果 fetch Promise尚未解决,在一定秒数后,我想向用户显示超时错误。

我在此处看到了一些添加 setTimeout 的好例子:https : //github.com/github/fetch/issues/175

但是如何处理也使用 redux 的 fetch promise 超时?例如

export function getData() {
  return (dispatch, getState) => {
    fetch('blah.com/data')
    .then(response => response.json())
    .then(json => dispatch(getDataSuccess(json)))
    .catch(
      error => {
        console.log(error)
      }
    )
      dispatch({
        type: DATA_FETCH_REQUEST
      })
  }
}

谢谢阅读!

2个回答

我一直渴望有一个使用 Promise.race 的理由,它非常适合这个用例。Promise.race 等待第一次解析或第一次拒绝。因此,如果拒绝首先触发,那么它永远不会触发thenPromise.race。更多在这里https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race抱歉,我没有机会测试代码。

export function getData() {
  return (dispatch, getState) => {
    let timeout = new Promise((resolve, reject) => {
      setTimeout(reject, 300, 'request timed out');
    })
    let fetch = new Promise((resolve, reject) => {
      fetch('blah.com/data')
        .then(response => response.json())
        .then(json => resolve(json))
        .catch(reject)
    })
    return Promise
      .race([timeout, fetch])
      .then(json => dispatch(getDataSuccess(json)))
      .catch(err => dispatch(getDataTimeoutOrError(err)))
  }
}

根据您提到的 github 片段,您可能可以执行以下操作:

function timeoutPromise(ms, promise) {
  return new Promise((resolve, reject) => {
    const timeoutId = setTimeout(() => {
      reject(new Error('Timeout'));
    }, ms);
    promise.then(
      (res) => {
        clearTimeout(timeoutId);
        resolve(res);
      },
      (err) => {
        clearTimeout(timeoutId);
        reject(err);
      }
    );
  })
}

export function getData() {
  return (dispatch, getState) => {
    dispatch({type: DATA_FETCH_REQUEST});

    timoutPromise(5000, fetch('blah.com/data'))
    .then(response => response.json())
    .then(json => dispatch(getDataSuccess(json)))
    .catch(
      error => {
        // Change this as necessary
        dispatch({type: DATA_FETCH_FAILED});
        console.log(error);
      }
    );
  }
}

如果您想向用户显示请求失败的信息,您可能需要处理类型为 的操作DATA_FETCH_FAILED