// promise allows us to write code for situations which say "when all of these things have happened do this one more thing". Promise is an object that is initially in a pending state and then can go to resolved(success) or rejected(failure) state. Once a promise reaches resolved or rejected state, it will remain in that state forever and its callbacks will not fire again. // a deferred object is like a promise with methods that allow its owner to resolve or reject. A promise object doesnt have methods that allow its owner to resolve or reject. Hence promise is a deferred object with resolve() and reject() methods missing. By calling deferred.promise() we can get hold of the promise object. // jquery's ajax methods do the same. They return a promise object so that the caller can not resolve or reject it. It would be odd if the caller was allowed to determine whether the ajax was successful or failed. // once we have a promise object we can attach as many callbacks as we like using done(), fail() and always() methods var divLoading = $("#divLoading"); divLoading.hide(); var container = $("#container"); var successFunc = function() { container.append("both calls succeeded"); divLoading.hide(); }; var failureFunc = function() { container.append("one or both calls failed"); divLoading.hide(); }; $("#btnLoad").click(function() { divLoading.show(); // execute a function after 2 ajax requests are successful or failed // here we have 2 promises. The successFunc is called if both promises are succesful. failureFunc is called if either one or both promises fail. // then is providing the success and failure callbacks $.when($.ajax("/somerequest"), $.ajax("/someotherrequest")).then(successFunc, failureFunc); }); // this example shows how we can chain multiple success and failure functions. In current ajax method we can only specify one success and failure. var container1 = $("#container1"); $("#btnLoad1").click(function() { $.ajax("test.html").done(function(data) { container1.append('ajax request was successful 1' + "<br/>"); }).done(function(data) { container1.append('ajax request was successful 2' + "<br/>"); }).fail(function(data) { container1.append('ajax request failed 1' + "<br/>"); }).fail(function(data) { container1.append('ajax request failed 2' + "<br/>"); }); }); //pipe demo $("#btnPipe").click(function() { var container2 = $("#container2"); var def1 = $.Deferred(); container2.append(def1.state() + "<br/>"); def1.resolve(); container2.append(def1.state() + "<br/>"); def1 = $.Deferred(); container2.append(def1.state() + "<br/>"); def1.reject(); container2.append(def1.state() + "<br/>"); def1 = $.Deferred(); container2.append(def1.state() + "<br/>"); var def2 = def1.pipe(); // pipe returns a new promise that allows us to filter or process the values of a deferred through another function container2.append("def2: " + def2.state() + "<br/>"); def2.done(function(data){ container2.append('successful. processing number: ' + data + "<br/>"); }); def2.fail(function(data) { container2.append('failed. processing number: ' + data + "<br/>"); }); var randomnumber=Math.floor(Math.random()*11); console.log(randomnumber); def1.resolve(randomnumber); //try running first with this statement and later comment it out and uncomment the below statement //def1.reject(randomnumber); container2.append("def2: " + def2.state() + "<br/>"); });
<div id="divLoading">Loading...</div> <input id="btnLoad" type="button" value="Make some call"/> <div id="container"></div> <hr/> <input id="btnLoad1" type="button" value="Make another call"/> <div id="container1"></div> <hr/> <input id="btnPipe" type="button" value="Pipe Demo"/> <div id="container2"></div> <hr/>