使用$ timeout时保证链接

时间:2016-03-08 04:09:39

标签: angularjs angular-promise

我正在尝试理解promise API和链接,尤其是$timeout.then()一起使用的时间。我对以下内容的期望是,由于$timeout返回一个承诺,.then()在解决之前不会被调用。

但不是ABAB,而是一直是ABBA。

如何使用promise API确保在$timeout执行之前,长时间运行的呼叫(或使用.then()的延迟呼叫)是否已完成?

代码

angular
  .module('app', [])
  .controller('ThenCtrl', ThenCtrl);

function ThenCtrl($timeout, $q) {
  var vm = this;

  vm.items = [];

  $q.when(pushA()).then(pushB());

  $timeout(pushA, 5000).then(pushB());

  function pushA() {
    vm.items.push('A');
  }

  function pushB() {
    vm.items.push('B');
  }
}

标记

<div ng-app="app">
  <div ng-controller="ThenCtrl as vm">
    {{vm.items}}
  </div>
</div>

我已经设置了一个小提琴:https://jsfiddle.net/kan3c61t/

3 个答案:

答案 0 :(得分:14)

不要调用.then方法中的函数。

  $q.when(pushA()).then(pushB);
  //$q.when(pushA()).then(pushB());

  $timeout(pushA, 5000).then(pushB);
  //$timeout(pushA, 5000).then(pushB());

而是将函数作为参数传递给.then方法。 $q服务将保留稍后调用的函数。

$q服务的工作方式是将.then方法的参数存储为稍后要调用的函数。在这种情况下,$q服务正在存储pushB()返回的值,其副作用是立即将B推送到数组上。

DEMO on JSFiddle

答案 1 :(得分:6)

你走了。 我所做的实际上是在代码的success部分添加了then函数。

$timeout(pushA, 5000).then(function(success) {
    pushB()
  });

这是工作demo

您也可以像这样添加error function

 $timeout(pushA, 5000).then(function(success) {
    pushB()
  },function(error){console.log("Error");});

在搜索这个答案时,我也遇到了这个问题helpful link

答案 2 :(得分:4)

正如其他人所说 - 你的更大问题是你.then(promise)而不是.then(function)

承诺代表价值+时间。它是已经开始运营的结果。承诺是一个值 - then等待函数。你不能在另一个承诺之后履行承诺&#34; - 因为承诺意味着操作已经开始。

then(x)函数以外的任何内容时,它将被忽略。这是承诺规范中的一个不幸的选择,但我们必须忍受它。

由于您的呼叫是同步的,因此您不应使用promises。如果您的代码执行了某些同步操作,则可以使用;而非then

对操作进行排序
pushA();
pushB(); 

如果它是一个返回promises的调用,那么它就变成了:

pushA().then(pushB);

调用$q.when将非承诺转换为承诺是没有意义的。

我把它写成:

pushA();
$timeout(5000).then(pushB); 

没有必要将第一个同步动作转换为promise返回函数,或者除了超时之外的任何地方都包含promise。如果您需要在{5000}之后发生pushA,我仍然可能会写:

$timeout(5000).then(pushA).then(pushB)

由于我认为它更具可读性,因此我们不会直接让pushApushB参与承诺。