如何使用 setTimeout 在 react native 中断获取请求



我正在尝试通过获取请求从服务器获取一些数据。有时网络会失败或发生类似的其他事情,我希望有一个超时以防止进一步的错误,并获得更好的体验。

实际上我想等待 20 秒,如果我没有得到任何响应,我想显示错误并中断获取请求。

我有一个加载模式,我可以在超时关闭它,但我也想中断获取请求。

这是我的获取请求代码:

_testPress = async () => { 
        //setTimeout(() => {this.setState({loading: false})}, 20000)
        this.setState({loading : true})
        fetch(getInitUrl('loginUser'), {
        method: 'POST',
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({          
          password : this.state.password,
          email : this.state.emailAddress,            
        }),
      }).then(response => Promise.all([response.ok, response.status ,response.json()]))
      .then(([responseOk,responseStatus, body]) => {        
        if (responseOk) {
          //console.log(responseOk, body);
          this._signInAsync(body.token);
          // handle success case
        } else {
          console.log(responseStatus);
          this.setState({
            showAlert : true,
            alertType : true,
            alertMessage : body.message
          });
        }
      })
      .catch(error => {
        console.error(error);
        // catches error case and if fetch itself rejects
      });
      }

我使用 setTimeout 关闭加载模块,但它不会停止我希望它在 20 秒后停止的实际请求。

请帮助我提供您的建议。感谢。

没有标准的参数可以添加到fetch ,但您可以完成以下解决方法:

// creating a wrapper for promises
function timeout(milliseconds, promise) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject(new Error("timeout exceeded"))
    }, milliseconds)
    promise.then(resolve, reject)
  })
}
// using that wrapper with fetch
timeout(1000, fetch('/api'))
  .then(function(response) {
     // response success
}).catch(function(error) {
  // timeout error or server error
})

例子:

超出超时:

// creating a wrapper for promises
function timeout(milliseconds, promise) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject(new Error("timeout exceeded"))
        }, milliseconds);
        promise.then(resolve, reject);
    });
}
  
const requestErr = new Promise((resolve, reject) => {
    setTimeout(() => {
        // request finished.
        resolve();
    }, 2500);
})
timeout(1000, requestErr)
    .then(function(response) {
        console.log("OK!");
    }).catch(function(error) {
        console.log("ERROR TIMEOUT!");
    });

未超过超时:

// creating a wrapper for promises
function timeout(milliseconds, promise) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject(new Error("timeout exceeded"))
        }, milliseconds);
        promise.then(resolve, reject);
    });
}
const requestOk = new Promise((resolve, reject) => {
    setTimeout(() => {
        // request finished.
        resolve();
    }, 500);
})
timeout(1000, requestOk)
    .then(function(response) {
        console.log("OK!");
    }).catch(function(error) {
        console.log("ERROR TIMEOUT!");
    });

您还可以使用具有自己的超时设置的 AXIOS

您可以通过将

"信号"传递到获取选项中来中止获取请求。

AbortSignal 对象实例;允许您与获取请求通信,并在需要时通过 AbortController 中止它。

https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch

完整的代码示例在这里。

https://javascript.info/fetch-abort

let controller = new AbortController();
fetch(url, {
  signal: controller.signal
});
controller.abort();

Fetch 没有实现连接超时。您也无法中止抓取请求。

看看这个要点,它围绕抓取请求包裹了一个Promise.race。一旦其中一个承诺(获取或超时(解析或拒绝,承诺就会解析:
https://gist.github.com/davej/728b20518632d97eef1e5a13bf0d05c7

这样的事情应该有效:

Promise.race([
  fetch(getInitUrl('loginUser'), *...fetchparams* ), 
  new Promise((_, reject) =>
    setTimeout(() => reject(new Error('Timeout')), 7000)
  )
]).then(*stuff*).catch(*stuff*)

或者,您也可以尝试一下 axios,这是一种获取的替代方案,支持超时:https://github.com/axios/axios

最新更新