【问题标题】:Invoking http.get sequentially when the list length is unknown当列表长度未知时,顺序调用 http.get
【发布时间】:2016-07-02 17:19:50
【问题描述】:

假设我有以下内容:

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

每个 url 都是“后备”,只有在无法访问前一个时才应使用。换言之,该列表指定了优先级。让我们还假设这个列表可以是任意长度 - 我不知道并且必须迭代。

我该如何编写一个函数,比如说“可达性”,它遍历这个数组并返回第一个可达的服务器?

我不能做$http.all,因为它是并行的。我无法运行带有$http.getwhile 循环,因为结果可能会在稍后出现,与此同时,我的用户界面将冻结。

请注意我没有使用 jQuery。我正在使用 ionic,它有一个 jQuery-lite 版本。

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

谢谢

【问题讨论】:

  • 你怎么能有一个未知长度的数组呢? myurls.length?

标签: javascript angularjs promise


【解决方案1】:

只需对数组进行归约:

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

流程说明:

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

在您的情况下,由于您正在重试失败,因此您想构建一个重试(或拒绝)链,因此我们必须从 Promise.reject() 开始。 Promise.reject().catch(func1).catch(func2)

【讨论】:

  • 我从来不知道存在 reduce。虽然您的解决方案看起来很棒,但我必须承认我的 JS 技能太基础,无法完全理解它。介意告诉我这里的流程吗?具体来说,我在哪里可以了解 ()=> 的作用?
  • 这是一个arrow function,在这种情况下只是一个简写。如果愿意,请将x => x*x 替换为function(x) { return x*x; }
  • 谢谢。看起来我只能接受 1 个答案,而不是 2 个。由于我使用的是 sp00m 的解决方案,因此我想将其作为我接受的选择。我从你的回答中学到了很多新东西。
  • 不用担心,只是想指出递归是唯一解决方案的情况(其中长度确实提前未知),但这不是其中之一.
【解决方案2】:

我猜递归和链接可以满足您的需求:

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

【讨论】:

  • 非常感谢。这很好用。我已经开始编写递归例程,但您的代码要优雅得多。
  • 我正在重新查看这段代码,想知道为什么我们不需要在第 4 行返回 $q.resolve(urls[0]) 而只是 return urls[0] 有效?
  • @user1361529 因为then 方法返回Promise,请参阅developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
猜你喜欢
  • 2018-07-06
  • 2014-09-09
  • 2015-07-22
  • 2017-04-18
  • 1970-01-01
  • 2018-10-20
  • 1970-01-01
  • 1970-01-01
  • 2011-12-31
相关资源
最近更新 更多