You may have overheard Promises, and a lot of people are talking about it, using it, but you don't know why they are so special. Can't you use callbacks? What's special? In this article, let's take a look at what Promises are and how to use them to write more elegant JavaScript code.
Promises Easy to read
For example, we want to grab some data from the HipsterJesus API and add this data to our page. The response data of these APIs is as follows:
{ "text": "<p>Lorem ipsum...</p>", "params": { "paras": 4, "type": "hipster-latin" }}To use callbacks, we usually write something like the following:
$.getJSON('http://hipsterjesus.com/api/', function(data) { $('body').append(data.text); });If you have experience using jQuery, you will recognize that we created a GET request and want the response to be JSON. We also pass a callback function to accept the response's JSON to add the data to the document.
Another way to write is to use the promise object returned by the getJSON method. You can bind a callback directly to this return object.
var promise = $.getJSON('http://hipsterjesus.com/api/');promise.done(function(data) { $('body').append(data.text); });In the above callback example, it adds the result of the API request to the document when the response is successful. But what happens when the response fails? We can bind a failed processor on our promise.
var promise = $.getJSON('http://hipsterjesus.com/api/');promise.done(function(data) { $('body').append(data.text);});promise.fail(function() { $('body').append('<p>Oh no, something went wrong!</p>'); });Most people delete the promise variable, which is more concise and can see the function of the code at a glance.
$.getJSON('http://hipsterjesus.com/api/').done(function(data) { $('body').append(data.text);}).fail(function() { $('body').append('<p>Oh no, something went wrong!</p>'); });jQuery also contains an event handler that happens all the time, and will be called regardless of the request success or failure.
$.getJSON('http://hipsterjesus.com/api/').done(function(data) { $('body').append(data.text);}).fail(function() { $('body').append('<p>Oh no, something went wrong!</p>');}).always(function() { $('body').append('<p>I promise this will always be added!.</p>'); });By using promises, the order of callbacks is as expected. We can make sure that the normal callback is called first, then the failed callback, and finally the callback that keeps happening.
Better API
For example, we want to create an encapsulated object of the HipsterJesus API. We will add a method - html, which returns HTML data from the API. Unlike setting up a callback processor to parse requests, we can have the method return a promise object.
var hipsterJesus = { html: function() { return $.getJSON('http://hipsterjesus.com/api/').then(function(data) { return data.text; }); }};This is cool so we can bypass the promise object without worrying about when or how to parse its value. Any code that requires a promise return value can be registered with a successful response callback.
The then method allows us to modify the result of the promise and pass it to the next processor in the chain. This means that now we can use the new API like this:
hipsterJesus.html().done(function(html) { $("body").append(html); });Until recently, AngularJS has a killer feature, where templates can be directly bound to promises. In Angular's controller, like this:
$scope.hipsterIpsum = $http.get('http://hipsterjesus.com/api/');In this way, it is very easy to write {{ hipsterIpsum.text }} in the template. When promise resolves, Angular does not need to automatically update the view. Unfortunately, the Angular team has abandoned this feature. It can now be enabled by calling $parseProvider.unwrapPromises(true). I hope that Angular already has this feature included in other frameworks (I will keep an eye on it).
Chain call
The best part about Promise is that you can tie them together. For example, we want to add a method to an API that returns an array.
var hipsterJesus = { html: function() { return $.getJSON('http://hipsterjesus.com/api/').then(function(data) { return data.text; }); }, paragraphs: function() { return this.html().then(function(html) { return html.replace(/<[^>]+>/g, "").split(""); }); }};We use this HTML method in the above method, we use it in the paragraphs method. Because the return value of the promise callback function is passed to the next callback in the chain, we are free to create small, functional methods to change the data when passing through them.
We can connect promises any time as needed. Let's add one.
var hipsterJesus = { html: function() { return $.getJSON('http://hipsterjesus.com/api/').then(function(data) { return data.text; }); }, paragraphs: function() { return this.html().then(function(html) { return html.replace(/<[^>]+>/g, "").split(""); }); }, sentences: function() { return this.paragraphs().then(function(paragraphs) { return [].concat.apply([], paragraphs.map(function(paragraph) { return paragraph.split(/. /); })); }); }};Multiple calls
Perhaps the most prominent feature of promise is the ability to call multiple APIs. What happens if you need to create two API calls at the same time when using a callback? You might write this:
var firstData = null;var secondData = null;var responseCallback = function() { if (!firstData || !secondData) return; // do something}$.get("http://example.com/first", function(data) { firstData = data; responseCallback();}); $.get("http://example.com/second", function(data) { secondData = data; responseCallback(); });This is much easier to use promise:
var firstPromise = $.get("http://example.com/first"); var secondPromise = $.get("http://example.com/second"); $.when(firstPromise, secondPromise).done(function(firstData, secondData) { // do something });Here we use the when method to bind it to a processor that is called when both requests are completed.
in conclusion
This is Promise. I hope you will immediately think of some terrible things that can be achieved with Promise. What do you like most about using them? Tell me in the comments!
*Note: For simplicity, this article uses the delayed execution of jQuery. There are subtle differences between the jQuery Deferred object and the Promises/A+ specification, which is more standard.
The above article How to use Promises to write more elegant JavaScript code is all the content I share with you. I hope it can give you a reference and I hope you can support Wulin.com more.