Asynchronous JavaScript and Promise

Source: Internet
Author: User

asynchronous?

I've seen it in a lot of places. Asynchronous (asynchronous)This word, but when I do not quite understand the concept, but found that they are often regarded as "already very clear" (* ̄? ̄).

If you have a similar situation, it doesn't matter, search the word, you can get a general description. Here, I'll make a little extra explanation for JavaScript async.

Take a look at this piece of code:

JavaScript code
    1. var start = new Date ();
    2. setTimeout (function() {
    3. var end = new Date ();
    4. Console.log ("Time Elapsed:", End-start, "MS");
    5. }, 500);
    6. while (new Date-start <) {};
This code is run and you get a result like time elapsed:1013ms. The function that setTimeout () sets to execute at the next 500ms is actually waiting for more time than 1000ms to execute.

How do you explain it? When SetTimeout () is called, a delay event is queued. Then, continue with the code after that, as well as the code behind it, until there is no code. Without any code, the JavaScript thread goes idle, and the JavaScript execution engine goes through the queue, finds the "should fire" event in the queue, and then calls the processor (function) of the event. Once the processor finishes executing, it returns to the queue and then looks at the next event.

Single-threaded JavaScript, that's how it works through queues, in the form of event loops. So, in the previous code, the execution engine was dragged in while the code was running for up to 1000ms, and no events were triggered until all the code had finished running back to the queue. This is the asynchronous mechanism of JavaScript.

The async puzzle for JavaScript

Asynchronous operations in JavaScript may not always be straightforward.

Ajax is perhaps the most asynchronous operation we can use. In jquery, for example, the code that initiates an AJAX request is typically:

JavaScript code
    1. //Ajax request schematic code
    2. $.ajax ({
    3. Url:url,
    4. Data:dataobject,
    5. success: function() {},
    6. Error: function() {}
    7. });
What's the problem with this writing? Simply put, it's not light enough. Why do we have to write success and error callbacks in the place where the request is initiated? If my callback is going to do a lot of things, do I have to think of one thing and run back here and add the code?

For example, we have to accomplish such a thing: There are 4 URL addresses for AJAX access, need to first AJAX access 1th, after the 1th access is completed, with the return data obtained as parameters and then access 2nd, 2nd after the completion of the visit 3rd ... With this to 4 all accesses complete. In this way, it seems to be the case:

JavaScript code
    1. $.ajax ({
    2.   url:url1,
    3.   ;  success: function (data) {
    4.     $.ajax ({
    5.     url:url2,
    6.     data:dat A,
    7.     success: function (data) {
    8. li>       $.ajax ({
    9.           //...
    10.       });
    11.     }  
    12.     });
    13.   
    14. })
You must think this code called Pyramid of Doom (Pyramid Doom) looks awful. Accustomed to the direct addition of callbacks, it is possible to pass this one to the next asynchronous event feel impossible to start. Naming and separating these callback functions can reduce nesting in form, making the code clear, but still does not solve the problem.

Another common difficulty is to send two AJAX requests at the same time, and then to do one more thing after all two requests have been successfully returned, and think about how it might seem a bit difficult to add callbacks only in the way they were called in front of each other?

Suitable for these asynchronous operations, it is promise that allows you to write more elegant code.

promise to play .

What is promise? Let's go ahead with the AJAX request code for the previous jquery example, and that code can actually be written like this:
JavaScript code
    1. var promise = $.ajax ({
    2. Url:url,
    3. Data:dataobject
    4. });
    5. Promise.done (function() {});
    6. Promise.fail (function() {});
This is equivalent to the previous AJAX request schematic code. As you can see, the addition of promise makes the code form change. The AJAX request is "saved" as if it were a variable assignment. This is encapsulation, and encapsulation will really make asynchronous events easier.

Encapsulation is a useful promise object that is like a well-encapsulated reference to an asynchronous event. Want to do something after this asynchronous event is complete? Add a callback to it, no matter how many you attach!

The Ajax method of jquery Returns a Promise object (this is the feature that the jQuery1.5 emphasis adds). If I have Do1 (), Do2 () two functions to execute after the successful completion of an asynchronous event, you only need to do this:

JavaScript code
    1. Promise.done (DO1);
    2. //other code here.
    3. Promise.done (DO2);
This is much more free, I just save this promise object, and at any time I write the code, I append any number of callbacks to it, regardless of where the asynchronous event originated. This is the advantage of promise.

A formal introduction

Promise dealing with asynchronous operations is so useful that the development of a specification for COMMONJS is called promises/a. Promise represents the return value at the end of an operation, which has 3 states:

    • Yes (fulfilled or resolved), indicating that the operation of the promise was successful.
    • negation (rejected or failed), indicating that the operation of the promise failed.
    • Wait (pending), has not received a positive or negative result, in progress.
In addition, there are 1 nominal states used to indicate that the promise operation has succeeded or failed, that is, the set of positive and negative states, called End (settled)。 Promise also has the following important features:
    • A promise can only transition from a waiting state to a positive or negative state once, and once it transitions to a positive or negative state, it will never change state.
    • If you add a callback for success or failure after the end of a promise (success or failure, with the previous description), the callback function executes immediately.
Consider an AJAX operation that initiates a request, waits, and then successfully receives a return or an error (failure). Is this quite consistent with promise?

There is also a good example of a further explanation of Promise's features: jquery's $ (document). Ready (Onready). Where the Onready callback function executes after the DOM is ready, but interestingly, if the DOM is ready before the code is executed, the Onready executes immediately without any delay (that is, synchronous).

Promise Example

Generate Promise

PROMISES/A lists a series of JavaScript libraries that implement promise, and jquery is among them. Here's the code for generating promise with jquery:

JavaScript code
    1. var deferred = $. Deferred ();
    2. Deferred.done (function(message) {Console.log ("Done:" + Message)});
    3. Deferred.resolve ("Morin"); //Done:morin
JQuery has deliberately defined a class named Deferred, which is actually promise. $. The Deferred () method returns a newly generated promise instance. On the one hand, using Deferred.done (), Deferred.fail () and so on for it to append callbacks, on the other hand, call Deferred.resolve () or deferred.reject () to affirm or negate this promise, and can pass arbitrary data to the callback.

Merging Promise

Remember what I said earlier about the challenge of sending 2 Ajax requests at a time? To continue with jquery as an example, promise will be able to solve it this way:

JavaScript code
    1. var promise1 = $.ajax (URL1),
    2. Promise2 = $.ajax (url2),
    3. promisecombined = $.when (Promise1, promise2);
    4. Promisecombined.done (ondone);
The $.when () method merges multiple promise to get a new promise, which is equivalent to establishing an and (logical-to) relationship between the original promise, and if all the constituent promise are successful, the merged promise is also successful. If any of the constituent promise fails, the merged promise fails immediately.

Cascade Promise

Then proceed to the question of a series of asynchronous tasks that I have previously executed sequentially. It will use the promise most important. Then () method (in the PROMISES/A specification, the "then () method Object" is used to define the promise). The code is as follows:

JavaScript code
    1. var promise = $.ajax (URL1);
    2. promise = Promise.then (function(data) {
    3. return $.ajax (url2, data);
    4. });
    5. promise = Promise.then (function(data) {
    6. return $.ajax (url3, data);
    7. });
    8. // ...
The complete form of the Promise. Then () method is. Then (Ondone, Onfail, onprogress), so that it looks like a handy way to attach various callbacks (. Done (),. Fail (). Yes, you can really use that, which is equivalent.

But the. Then () method also has its more useful functionality. Like then the meaning of the word itself, it is used to clearly indicate the pre-and post-relationship of an asynchronous event: "This first, then again". This is called a cascade of promise.

To Cascade Promise, be aware that in the callback function passed to then (), be sure to return the promise you want to represent the next task ($.ajax (URL2, data) of the above code). In this way, the previously assigned variable will become the new promise. If then () 's callback function returns not promise, then the then () method returns the original promise.

Should be a little hard to understand? From the point of view of code execution, this piece of code with multiple then () is actually run over by the JavaScript engine. But it's like writing a good stage play, and after reading it, the JavaScript engine will arrange for the actors to play according to the script in the next moment, and the performance is all asynchronous. The then () method is to allow you to write the pen of the asynchronous script.

use Promise with callback function-based APIs

The $.ajax () method, which is used repeatedly in the previous article, returns a Promise object, which is actually a benefit that jquery specifically provides. The reality is that most JavaScript APIs, including native functions in node. js, are based on callback functions and not on promise. In this case, the use of promise will need to do some self-processing.

This process is actually relatively simple and straightforward, here is an example:
JavaScript code
    1. var deferred = $. Deferred ();
    2. SetTimeout (deferred.resolve, +);
    3. Deferred.done (ondone);
In this way, the promise positive or negative trigger, as the API callback, becomes the Promise processing mode.

How did promise come into being?

This article writes promise writes here, you found that all is based on the existing implementation of the Promise Library. So, what if you want to build a promise yourself?

The first q of the list of libraries in promises/a is the most promises/a-compliant and fairly straightforward implementation. If you want to know how to make a promise, you can refer to the design pattern parsing provided by Q.

Confined to space, this article only describes the application of promise. I will write a separate article in the future to detail the implementation details of promise.

As a subsequent version of JavaScript ECMAScript 6 will be native to provide promise, if you want to know its usage, it is recommended to read JavaScript Promises:there and back again.

Conclusion

Promise the word stubborn to not suitable for translation, under one eye will feel the meaning is unclear. However, it does provide quite a bit of help in JavaScript when it comes to complex asynchronous tasks.


Original: http://segmentfault.com/blog/yardtea/1190000002526897

Asynchronous JavaScript and promise

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.