【问题标题】:Most efficient way to receive json async responses?接收 json 异步响应的最有效方法?
【发布时间】:2015-02-09 02:04:13
【问题描述】:

(我的案例适用于 C#、MVC、返回 JSON、得到 jquery、角度),但我希望它适用于更多。

我有一个网站,我的 angular/html/js 通过 Angular 控制器调用 ~7 个服务并异步获取/显示数据(天气、路况等)。其中一些需要比其他时间更长的时间(从 ms 到 ~10s)。我想对我的服务进行一次调用,它会返回所有这些数据 - 但不要等到最后一次调用返回任何东西(10 秒)。

有没有办法进行一次调用,并在我拥有结果时返回结果并相应地显示?我是否需要重复调​​用具有类似“IsMore=T”的布尔值并再次调用服务? (听起来效率不高)。

理想情况下,我希望保持响应渠道畅通,并保持抽出结果,直到完成。可能吗?

【问题讨论】:

  • 您目前是否发出 7 个 HTTP 请求并且只想发出一个请求?
  • 是的(对我的服务)——但我不想等到我有最后一个数据 ~10 秒后才显示第一个数据
  • 如果您向服务器发出七个异步请求,服务器可以并行处理所有七个请求,并在每个响应可用时返回每个响应。当每个响应到达时,由您的客户做出反应。如果您发出一个请求,那么服务器会发出一个响应,这在所有处理完成之前很可能不会发生。您的服务器代码可以将请求分成七个线程并对其进行处理,但这会不必要地使服务器代码和客户端代码复杂化。除非你能证明网络延迟有问题,否则我会坚持使用七个请求。
  • 根据您的描述,我同意 Hobo Sapiens,但如果您确实需要服务器到客户端通道,请查看 SignalR - signalr.net

标签: javascript json asp.net-mvc angularjs


【解决方案1】:

我不确定我是否完全理解,但我认为您可以将响应承诺链接在一起,例如:

$scope.getWeatherData = function () {
  return myWeatherService.get().then(function (resp) {
    $scope.weatherData = resp;   
  });
}

$scope.getTrafficData = function () { 
  return myTrafficService.get().then(function (resp) {
    $scope.trafficData = resp;
  });
}

$scope.getWeatherData.then(getTrafficData).then(...chain others...);

这假设服务调用返回一个$http 承诺。

无论如何,只要 promise 到来,数据就会在 $scope 上,因此显示会随着 promise 的到来而更新。听起来您可能正在使用类似$q.all() 的东西,它会等到所有承诺都得到解决。

【讨论】:

  • 谢谢,恰恰相反——我想要一个调用(优化调用),它立即返回第一个出现的内容,然后返回任何第二个出现的内容,直到最后一个,而无需等待为最后一件事显示第一件事。此外,它们可能有不同的顺序,因此链接也不会以这种方式工作(即使它的工作方式相反)。 Hobo Sapiens 回复可能有效 - 我没有发现网络丢失(它在 Azure 上,所以它是 SOLID),但是我有成千上万的客户端,经常刷新(缓存,但仍然)。可能还不错。
【解决方案2】:

建立在@reptilicus 的回答之上:

$scope.getWeatherData = function () {
  return myWeatherService.get().then(function (resp) {
    $scope.weatherData = resp;   
  });
};

$scope.getTrafficData = function () { 
  return myTrafficService.get().then(function (resp) {
    $scope.trafficData = resp;
  });
};

$q.all([
  $scope.getWeatherData(), 
  $scope.getTrafficData()
]).then(function () {
 // do whatever's next, or nothing
});

... 将并行请求/接收两个响应(如果这是您想要的)。当收到相关响应时,每个请求的相关 $scope 属性将被填充,并且一旦它们全部完成,“dowhatwhat's next”代码将运行。

注意,您需要将 $q 注入控制器构造函数才能使其工作。 :)

编辑:我刚刚注意到@reptilicus 确实提到了$q.all。链接.thens 和 $q.all 之间的区别在于,在链接下,一个请求在收到前一个请求之前不会开始......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-04
    • 2013-08-26
    • 2020-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多