Promises are a concept. This is a question on AngularJS Promises, which are a bit different from other promises, but the concept across libraries are fundamentally the same.
What are Asynchronous Processes?
If you know what this is, skip it and read the next header, otherwise:
When you have code, it generally runs in sequential order like so:
object.method() // First,
variable = "something"; // Second,
for(var i=0; i<2; i++) {
resp = object.makeHttpRequest();
console.log(resp.data + " was #" + i);
} // Third,
console.log("Done"); // Last.
Each step is performed after the previous finishes. This can be a problem when that for
loop takes a long time (imagine the HTTP request takes a long time). The request would hang an entire process until the HTTP request is finished. Very bad.
Node.js handles this by default using a callback pattern. When you call a function that is blocking (takes a long time, like reading a file on disk or making an HTTP request), you register a callback function it will call after finishing. It will apply
the function with the data from the blocking function when it finishes. This allows you to run other code while that blocking function finishes.
As many Node.js developers will tell you, this code can get very messy, very fast. Instead, AngularJS (and other libraries) will return you a Promise for when the code will finish. It allows you to use a Promise Pattern.
I know what asynchronous stuff is
Promises are conceptually similar to callbacks, but much cleaner and allow a greater degree of control. Consider this:
var url = getUrlFunction();
makeHttpRequest(url, function onResponse(data) {
dataHandler(data);
console.log("done");
}, function onError(err) {
errHandler(err);
console.log("uh oh");
});
showTheUserWeAreLoading();
// Or in node.js
var url = getUrlFunction();
makeHttpRequest(url, function onResponse(err, data) {
(err) ? handleErr(err): null;
dataHandler(data);
console.log("done");
});
showTheUserWeAreLoading();
It is not very intuitive that the showTheUserWeAreLoading
function will (sometimes) happen before the HTTP request if fulfilled. This leaves much to be desired when rereading your own code.
The same code, but with the makeHttpRequest
returns a promise:
var url = getUrlFunction(), prom = makeHttpRequest(url);
showTheUserWeAreLoading();
prom.then(function onSuccess(data) {
dataHandler(data);
console.log("done");
}, function onError(err) {
errHandler(err);
console.log("uh oh");
});
The promise object helps track the state of the operation. You assign handlers for when the operations reaches one of two states: Fulfilled or Rejected.
It should be noted that makeHttpRequest
is a stand-in for $http()
in AngularJS or $.ajax
in jQuery. Before the standard for promises was created in the ECMAScript standard, each library (and library version) had its own opinion on which pattern you should/can use. AngularJS previously used the .success(<function>).error(<function>)
naming pattern, while jQuery used .done(<function>).fail(<function>)
. These naming schemes have been depreciated a very long time ago, therefore making the current difference between libraries unnoticeable (thank you ECMAScript).