【问题标题】:No timeout called on second call to fetch第二次调用 fetch 时没有调用超时
【发布时间】:2019-11-01 16:18:12
【问题描述】:

我在 React-Native 中有一个登录页面。如果我有 Internet 连接,它可以正常工作,但我现在想处理 Internet(或服务器)关闭的情况。我想这样做的方法是使用超时:应用程序应该尝试连接,如果五秒钟内没有成功,我想打印一条错误消息。

我使用以下代码完成了这项工作,取自here

export function timeout(
  promise,
  message = 'Request timeout',
  timeout = DEFAULT_TIMEOUT,
) {
  return new Promise((resolve, reject) => {
    const timeoutId = setTimeout(() => {
      console.log('timeout called');
      reject(new Error(message));
    }, timeout);
    promise.then(
      response => {
        clearTimeout(timeoutId);
        resolve(response);
      },
      err => {
        console.log('timeout NOT called');
        clearTimeout(timeoutId);
        reject(err);
      },
    );
  });
}

从登录页面,我们这样称呼它:

response = await timeout(
   getAccessToken(this.state.username, this.state.password),
  'Unable to connect to the server.',
);

其中getAccessTokenfetch 的异步包装器。它在第一次登录尝试时工作正常(互联网关闭)。它等待五秒钟 (DEFAULT_TIMEOUT),然后打印“无法连接到服务器”错误消息。问题是,如果我再次单击登录按钮,该应用程序不会等待五秒钟并打印一个通用的“网络错误”。我们可以在logkitty看到问题:

[12:08:44] I | ReactNativeJS ▶︎ timeout called                (first click)
[12:08:49] I | ReactNativeJS ▶︎ timeout NOT called            (second click)

我不明白为什么在第二次登录尝试时未触发超时并且timeout 自动失败。有什么问题,我该如何解决?

【问题讨论】:

  • getAccessToken 函数是 Promise??
  • @hongdevelop 是的,它返回一个承诺

标签: javascript react-native timeout fetch-api


【解决方案1】:

当网络故障或请求未完成时,从fetch() 返回的Promise 对象为rejected

如果出现网络错误或服务器端CORS配置错误,import()预约会被TypeError拒绝,所以第二次尝试会识别TypeError并立即进入拒绝状态。

要再次超时,您必须在连接 Internet 后运行fetch() 函数。然后你必须再次关闭互联网并运行fetch()

注意:从 fetch() 返回的 Promise 对象不会拒绝 HTTP 错误状态。即使 HTTP 状态码返回 404 或 500。

【讨论】:

  • 所以这是预期的行为(从fetch 的角度来看)?在研究这个问题时,我没有发现任何关于此问题的信息,您能用参考来支持您的答案吗?谢谢!
  • 是的,这可以应用于所有 API 调用。例如,第一次调用API时,响应值可能会晚一些,但再次尝试时,响应值可能会比以前快。
  • 你所说的就是我所观察到的。问题竟然出在fetch standard,好像没有提到这个……
  • 这不是部分获取,而是承诺,你必须这样做。首次运行时创建一个名为 Promise 的对象。因为里面的参数也是第一次执行,所以对应的是接收和执行数据的变量。但是,在第二次运行时,Promise 已经有了数据。而且参数是一样的。这就是为什么 timeout reject reject err 作为函数先运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-11
相关资源
最近更新 更多