【问题标题】:JavaScript using fetch to check if a resource is reachable, with a timeoutJavaScript 使用 fetch 检查资源是否可访问,并有超时
【发布时间】:2017-03-27 22:01:04
【问题描述】:

几天前,我尝试实现一个函数来检查资源是否可访问。我对 JS 比较陌生,不得不重新构建我的完整代码,以实现建议的异步功能 here on SO

现在我已经按预期工作了,@adeneo 提供了上述答案。

但是,如果资源无法访问,该过程需要 2 分钟以上,所以我想为 fetch 命令实现超时。

我遇到了this answer on a GitHub issue

var p = Promise.race([
  fetch('/resource-that-may-take-a-while'),
  new Promise(function (resolve, reject) {
    setTimeout(() => reject(new Error('request timeout')), 5000)
  })
])
p.then(response => console.log(response))
p.catch(error => console.log(error))

我真的不熟悉JS,在这里有点迷茫。

如何在我已实现的功能中实现上述超时,并发布在我提到的 SO 问题上?

编辑:

因为在我的例子中,fetch('/resource-that-may-take-a-while') 更广泛一些,所以我尝试将建议的 Promise.race 包装在我已经拥有的工作代码周围。

结果是一种同时实现前一个 SO 问题的建议功能和 GitHub 的超时建议的方法。

function chk(target, times, delay) {
    var p = Promise.race([
    return new Promise((res, rej) => {

        (function rec(i) {
            fetch(target, {mode: 'no-cors'}).then((r) => {
                res(r);
            }).catch( err => {
                if (times === 0)
                    return rej(err);

                setTimeout(() => rec(--times), delay )
            });
        })(times);

    }),
  new Promise(function (resolve, reject) {
    setTimeout(() => reject(new Error('request timeout')), 5000)
  })
])
p.catch(error => console.log("timeout"));
}

这导致Uncaught SyntaxError: Unexpected token return 对应于return new Promise((res, rej) => { 行。

【问题讨论】:

  • 不能在数组声明语句中返回。只需省略 return 关键字即可。
  • 我可能错了,但我认为我需要在那里返回承诺,否则完整的 inner 函数永远不会返回任何内容。
  • Promise.race 在 fetch 或 timeout 承诺解决或拒绝时完成。无论您的 return 语句如何,都会调用 inner 函数 (rec)。此外,您不能从 Promise 回调中返回任何内容 - 这是回调的工作方式。使用p.then 处理获取工作的事件。使用p.catch(就像你已经做过的那样)来处理超时情况。

标签: javascript timeout fetch-api


【解决方案1】:

根据mdn

Promise.race(iterable) 方法返回一个 Promise,只要 iterable 中的一个 Promise 解析或拒绝,该 Promise 就会解析或拒绝,并带有来自该 Promise 的值或原因。

您需要做的就是将 Promise 传递到您传递给 Promise.race 函数的数组中。您不必返回那里 - 但您可以返回 chk 函数的 Promise 以直接使用它,如下所示。如果chk 或超时完成/失败,p 将解决/拒绝

var p = Promise.race([
  chk(t, 3, 1000),
  new Promise(function (resolve, reject) {
    setTimeout(() => reject(new Error('request timeout')), 5000)
  })
])

p.catch(error => console.log('timeout'))

function chk (target, times, delay) {
  return new Promise((res, rej) => {
    (function rec (i) {
      fetch(target, { mode: 'no-cors' }).then((r) => {
        res(r)
      }).catch(err => {
        if (times === 0) {
          return rej(err)
        }

        setTimeout(() => rec(--times), delay)
      })
    })(times)
  })
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-20
    • 1970-01-01
    • 2017-08-03
    • 2016-03-03
    • 2017-07-30
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    相关资源
    最近更新 更多