NunoRibeiro
NunoRibeiro

Reputation: 511

Javascript callback() for two functions

I have two questions regarding the callback on JavaScript.

First: Does the for loop run asynchronously? That is, in the function:

function postData(items, callback)
{
   for(var i=0 ; i < items.length ; i++)
   {
      //angularjs Post request
      $http.post("http://www....", item[i]);
   }

   callback();
}

Will the callback() wait until the cycle is finished?

Second: How can I wait for a callback of two functions?

I have another function deleteData(items, callback) that I want to run async with the postData(). When the two are done I want to do some "refresh".

For now I'm using:

function postData(items, callback)
{
  for(var i=0 ; i < items.length ; i++)
   {
      //angularjs Post request
      $http.post("http://www....", item[i]);
   }

   callback();
}

function deleteData(items, callback)
{
  for(var i=0 ; i < items.length ; i++)
   {
      //angularjs delete request
      $http.delete("http://www....", item[i].id);
   }

   callback();
}

function refresh()
{
  $http.get("www....").success....
}

function doit(post, delete)
{
   postData(post, function(){
      deleteData(delete, function(){
          refresh();
      })
   });
}

Is it possible to make postData and deleteData run assync and when the both are done run the refresh?

----- EDIT -----

To make sure that the callback is send after the cycle is done, I use the code like this:

function postData(items, callback)
{
  if(items.length == 0)
    callback();
  for(var i=0 ; i < items.length ; i++)
   {
      //angularjs Post request
      $http.post("http://www....", item[i]);

      if(i == items.length-1)
         callback();
   }

   callback();
}

But it looks ugly... I was hoping for a cleaner solution...

replying to Ivan, Angular has also callback for the http requests, I don't need to use $ajax and I don't want to callback for each http request

Upvotes: 1

Views: 572

Answers (2)

Andr&#233; Snede
Andr&#233; Snede

Reputation: 10045

Yes, using the $q promise library, you can achieve that. If you are using angular, $q is already in your project, just include it in the service/controller you are using.

$q.all does exactly what you are looking for.

Example of how it would look:

var promises = [];

// loop x times
for(var i = 0; i < items.length; i ++){
    var promise = $http.post("http://www....", item[i]);
    promises.push(promise);
}

// Refresh will be called when all posts are completed.
$q.all(promises).then(refresh); 

Upvotes: 2

Ivan
Ivan

Reputation: 789

First: no, it will not wait.

Second: Use $.ajax :

function postData(items, callback)
{
  for(var i=0 ; i < items.length ; i++)
   {
      $.ajax({
        url: "http://www....",
        ...........
      }).done(function() {
        callback();
      });
   }
}

Or alternatively vanilla JS:

function postData(items, callback)
{
  for(var i=0 ; i < items.length ; i++)
   {
      var r = new XMLHttpRequest(); 
      r.open("POST", "http://www....", true);
      r.onreadystatechange = function () {
      if (r.readyState != 4 || r.status != 200) return; 
        callback();
      };
   }
}

Upvotes: -1

Related Questions