JavaScript使用fetch检查资源是否可访问,超时

时间:2017-03-27 12:08:41

标签: javascript timeout fetch-api

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

现在,我已经按照预期的方式工作了,并提到了@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 returnreturn new Promise((res, rej) => {

1 个答案:

答案 0 :(得分:1)

根据mdn

  

Promise.race(iterable)方法返回一个promise,它会在iterable中的一个promise中解析或拒绝,并使用该promise中的值或原因解析或拒绝。

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

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)
  })
}