列表长度未知时顺序调用 http.get

Invoking http.get sequentially when the list length is unknown

假设我有以下内容:

var myurls = ['http://server1.com', 'http://server2.com', 'http:sever2.com', etc ]

每个 url 都是一个 "fallback",只有在无法达到前一个时才应使用。换句话说,这个列表指定了一个优先级。我们还假设这个列表可以是任意长度——我不知道并且必须迭代。

我该如何编写一个函数,假设 "reachability" 循环遍历此数组和 returns 第一个可访问的服务器?

我不能做 $http.all 因为它是并行的。我不能 运行 内部有 $http.getwhile 循环,因为结果可能会稍后出现,与此同时,我的 UI 会冻结。

请注意我没有使用 jQuery。我正在使用 ionic,其中包含 jQuery-lite 版本。

我看到的各种例子都在谈论在 .then 中链接它们,如果您事先知道 URL 的数量,这很好,但我不知道。

谢谢

我想递归和链接可以满足您的需要:

var findFirstReachableUrl = function (urls) {
  if (urls.length > 0) {
    return $http.get(urls[0]).then(function () {
      return urls[0];
    }, function () {
      return findFirstReachableUrl(urls.slice(1));
    });
  } else {
    return $q.reject("No reachable URL");
  }
}

通话:

findFirstReachableUrl(myurls).then(function (firstReachableUrl) {
  // OK: do something with firstReachableUrl
}, function () {
  // KO: no url could be reached
});

只需减少数组:

myurls.reduce((p, url) => p.catch(() => http.get(url).then(() => url)),
              Promise.reject());

流程说明:

它基于可能更多 common pattern 使用 reduce 构建承诺链,如下所示:[func1, func2].reduce((p, f) => p.then(f), Promise.resolve()); 等同于 Promise.resolve().then(func1).then(func2)([=13= 的最后一个参数]为初始值)。

在你的例子中,由于你在失败时重试,你想要构建一个重试(或拒绝)链,所以我们必须从 Promise.reject() 开始。 Promise.reject().catch(func1).catch(func2)