Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple chained deferred functions using q in AngularJS stop returning data

Tags:

angularjs

q

I am trying to chain together multiple deferred function calls such that the next call gets the results of the previous deferred.resolve. When I chain together more than 2 of these calls, the data stops being returned.

Here is the basic code inside an angular controller:

    $scope.runAsync = function() {         var asyncFn1 = function(data){             var deferred = $q.defer();              $timeout(function(){                 console.log("Async fn1 " + data);                 $scope.outputLines.push("Async fn1 " + data);                 deferred.resolve("Async fn1 " + data);             },1000);              return deferred.promise;         }          var asyncFn2 = function(data){             var deferred = $q.defer();              $timeout(function(){                 console.log("Async fn2 " + data);                 $scope.outputLines.push("Async fn2 " + data);                 deferred.resolve("Async fn2 " + data);             },1000);              return deferred.promise;         }          asyncFn1(1)         .then(function(data){asyncFn2(data)})         .then(function(data){asyncFn2(data)})         .then(function(data){asyncFn2(data)});     } 

When I run this I get the following output:

Async fn1 1 Async fn2 Async fn1 1 Async fn2 undefined Async fn2 undefined 

How can I chain them together so that the third call gets the result from the second call and the fourth gets the result from the third?

I have created a jsFiddle: http://jsfiddle.net/rhDyL/

like image 807
BoxerBucks Avatar asked Apr 17 '13 22:04

BoxerBucks


People also ask

What is Q defer () in AngularJS?

Simply put you can use $q. defer() to create a Promise. A Promise is a function that returns a single value or error in the future. So whenever you have some asynchronous process that should return a value or an error, you can use $q. defer() to create a new Promise.

What does $q do in AngularJS?

$q is an angular defined service. It's the same as new Promise(). But $q takes things to the next level by enhancing additional feature that developers can use to perform complex tasks more simply. resolve(value) – resolves the derived promise with the value.


1 Answers

Excerpt taken from the official doc on $q:

then(successCallback, errorCallback) – regardless of when the promise was or will be resolved or rejected calls one of the success or error callbacks asynchronously as soon as the result is available. The callbacks are called with a single argument the result or rejection reason.

This method returns a new promise which is resolved or rejected via the return value of the successCallback or errorCallback.

And for the return value of the successCallack or errorCallback, according to Domenic's slides:

if the return value is a promise then the promise adopts the returned promise's state otherwise the success callback is immediately called with the return value

Based on the definition, your code is missing the return keyword. It should be as following:

    asyncFn1(1)     .then(function(data){return asyncFn2(data)})     .then(function(data){return asyncFn2(data)})     .then(function(data){return asyncFn2(data)}); 
like image 61
tamakisquare Avatar answered Sep 29 '22 09:09

tamakisquare