2

I want to call two function say function a() and function b() in parallel. These functions are independent to each other, and lets say the time required to execute these two functions are not fixed. Sometimes function a() will take more time than function b() and vice versa. But there is another function c() that should only execute when both the functions a() and b() are completed.

How should I do this using jQuery's Deferred object?

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
Suraj Ahirrao
  • 182
  • 10
  • https://stackoverflow.com/questions/15018931/jquery-custom-deferred-functions Check it out – jack Jul 28 '17 at 10:33

5 Answers5

2

To achieve this you can make the a() and b() functions return deferred objects which you resolve() once their logic has completed. You can then run c() once both previous functions have completed. Try this:

function a() {
  var aDef = $.Deferred();
  setTimeout(function() {
    aDef.resolve('a done');
  }, 1000);
  return aDef;
}

function b() {
  var bDef = $.Deferred();
  setTimeout(function() {
    bDef.resolve('b done');
  }, 3000);
  return bDef;
}

function c() {
  console.log('all done!')
}

console.log('running...');
$.when(a(), b()).done(function(a, b) {
  console.log(a);
  console.log(b);
  c();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
0

I'd use a global variable to determ an operational status and execute a polling each 100 milliseconds (or each milliseconds if you need).

var myStatus = {
  "a": false,
  "b": false
};

function a() {
  myStatus["a"] = true;
  console.log(myStatus['a']);
}

function b() {
  myStatus["b"] = true;
}

function getStatusText() {
  var s = 'not complete';
  if (myStatus.a && myStatus.b) {
    s = 'all complete';
  } else {
    if (myStatus.a) {
      s = 'a complete';
    }
    if (myStatus.b) {
      s = 'b complete';
    }
  }
  return s;
}

function c() {
  //check operational status
  var statusText = getStatusText();
  document.getElementById('status').innerHTML = statusText;
}
setInterval(
  function() {
    c()
  }, 100);
<button onclick="a()">Set a() complete</button><button onclick="b()">Set b() complete</button>

<p>operational status <span id="status"></span></p>
Paolo Falomo
  • 427
  • 3
  • 15
0

Please refer Jquery defer and promise method to handle calls.

https://api.jquery.com/deferred.promise/ or

https://api.jquery.com/promise/

Varun Sreedharan
  • 517
  • 8
  • 28
0

This is not exactly an answer to the question. I don't use defer or anything like it.

But I want to show something I do quite often: add a onReady callback, as a parameter to a() and b(). I add these callbacks to any self-written-function that takes time to execute.

function a(onready) {
  // let's say we get Ajax data
  $.ajax({
    url: 'data.php',
    success: function(data) {
      $('#message').html(data);
      if(typeof onready == 'function') {
        onready();   // you might also want to add message as a parameter, like onready(data), or anready('Data okay'), ...
      }
    }
  });
}

function b(onready) {
  // let's say we sort <table> rows
  sortTable('my_table', 'my_row', 'ASC');  // this function (not provided here) is not asynchronous, it just takes time before it's done
  if(typeof onready == 'function') {
    onready();   
  }
}

function c() {
  alert('Yippy!');
}

$(document).ready(function() {  // or this could be after the client clicks on a button, or so
  var aReady = false;
  var bReady = false;

  a(function() {
    aReady = true;
    if(aReady && bReady) {
      c();
    }
  });

  b(function() {
    bReady = true;
    if(aReady && bReady) {
      c();
    }
  });

}); 
Emmanuel Delay
  • 3,619
  • 1
  • 11
  • 17
-1

You can use jQuery.when() to do this. Please read the document about this at https://api.jquery.com/jquery.when/

a = function () {
//your code for function a
}
b = function () {
//your code for function b
}

$.when( a(), b() ).done(function c() {
    //your code for function c
});