Promise in JavaScript using the basics

Source: Internet
Author: User
Tags error handling valid

Many languages, in order to process asynchronous patterns more in the usual order, contain an interesting scenario library, which is called promises,deferreds, or futures. The promises of JavaScript can facilitate separation of concerns to replace tightly coupled interfaces. This article is about the JavaScript promises based on the PROMISES/A standard. [Http://wiki.commonjs.org/wiki/Promises/A]

Use cases for promise:

    • Executing rules
    • Multiple Remote Authentication
    • Timeout processing
    • Remote Data request
    • Animation
    • Decoupling event logic from application logic
    • The terror triangle that eliminates the callback function
    • Controlling asynchronous operations in parallel

JavaScript promise is an object that promises to return a value in the future. is a data object that has well-defined behavior. There are three possible states of promise:

    1. Pending (to be determined)
    2. Rejected (rejection)
    3. Resolved (completed)

A promise that has been rejected or completed is settled. A commitment can only be changed from a pending state to an already resolved state. After that, the State of commitment will not change. A commitment can exist long after its corresponding processing has been completed. In other words, we can get the processing results multiple times. We get the result by calling Promise.then (), which returns only until the end of the process that the commitment corresponds to. We can be flexible in tandem to make a bunch of promises. These concatenated "then" functions should return a new commitment or the earliest promise.
With this style, we can write asynchronous code like write synchronization code. Mainly through the combination of commitment to achieve:

    • Stack task: Multiple places scattered in the code, corresponding to the same commitment.
    • Parallel tasks: Multiple commitments return the same commitment.
    • Serial tasks: One commitment, then another commitment to execute.
    • A combination of several of the above.

Why do you have to be so troublesome? Can't you just use the basic callback function?

Problems with callback functions

Callback functions are suitable for simple repetitive events, such as using a click to make a form valid, or to save the results of a rest call. The callback function also causes the code to form a chain, a callback function calls a rest function, and a new callback function is set for the rest function, the new callback function calls another rest function, and so on. The horizontal growth of the code is greater than the vertical growth. The callback function looks very simple until we need a result, and it is immediately necessary to use the next line of computation.

' Use strict ';
var i = 0;
function log (data) {Console.log ('%d%s ', ++i, data);
 
function Validate () {
  log ("Wait for it ...");
  Sequence of four long-running async activities
  settimeout (function () {
   log (' result i ');
   settimeout (function () {
     log (' result second ');
     settimeout (function () {
      log (' result third ');
      settimeout (function () {
        log (' result fourth ')
      }, 1000);
     }, 1000);
   }, 1000);
  }, 1000);
Validate ();

I use timeout to simulate asynchronous operations. The way to manage exceptions is painful, and it's easy to play with the downstream behavior. When we write callbacks, the code organization becomes cluttered. Figure 2 shows an analog verification stream that can run in Nodejs REPL. In the next section, we will migrate from the Pyramid-of-doom mode to a continuous promise.

Figure

' Use strict ';
var i = 0;
function log (data) {Console.log ('%d%s ', ++i, data);
 
Asynchronous FN Executes a callback result FN
function async (ARG, callback) {
  settimeout (function () {
   log ( ' Result ' + arg);
   CallBack ();
  }, 1000);
 
function Validate () {
  log ("Wait for it ...");
  Sequence of four long-running async activities Async
  (' A ', function () {
   async (' Second ', function () {
   async (' third ', function () {
      async (' Fourth ', function () {});
     })
;}; Validate ();

Results of execution in Nodejs REPL

$ node Scripts/examp2b.js
1 wait for it ...
2 Result-
3 result second
4 result third
5 result fourth
$

I have encountered a angularjs dynamic validation situation, depending on the value of the table, dynamic restrictions on the value of the table items. The range of valid values for a restriction item is defined on the rest service.

I wrote a scheduler to manipulate the stack of functions based on the requested value to avoid the callback nesting. The scheduler POPs the function from the stack and executes it. The callback of the function will recall the scheduler at the end until the stack is emptied. Each callback logs all validation errors returned from the Remote authentication call.

I think what I'm writing is an inverse pattern. If I use angular's $http call to provide promise, my mind will be more linear in the whole validation process, like synchronous programming. The flattened promise chain is readable. Go on...

using promises

The Kew Promise Library is used. Q Library also applies. To use the library, first use NPM to import the Kew library into Nodejs, and then load the code into Nodejs REPL.

Figure

' Use strict ';
var Q = require (' Kew ');
var i = 0;
 
function log (data) {Console.log ('%d%s ', ++i, data);
 
Asynchronous FN Returns a promise
function async (ARG) {
  var deferred = Q.defer ();
  settimeout (function () {
    deferred.resolve (' result ' + arg); \
  }, 1000);
  return deferred.promise;
};
 
Flattened promise chain
function validate () {
  log ("Wait for it ...");
  Async (' i '). Then (function (RESP) {
    log (resp);
    Return Async (' second ');
  })
  . Then (function (RESP) {
    log (resp);
    Return Async (' third ')
  })
  . Then (function (RESP) {
    log (resp);
    Return Async (' fourth ');
  })
  . Then (function (RESP) {
    log (resp);
  }). Fail (log);
Validate ();

Output is the same as using nested callbacks:

$ node Scripts/examp2-pflat.js
1 wait for it ...
2 Result-
3 result second
4 result third
5 result fourth
$

The code is a little "tall", but I think it's easier to understand and modify. It is easier to add appropriate error handling. Call fail at the end of the chain to catch the error in the chain, but I can also provide a reject handler in any then to do the corresponding processing.

Server or browser

Promises is as effective in the browser as it is in the Nodejs server. The following address, http://jsfiddle.net/mauget/DnQDx/, points to a jsfiddle show how to use a Promise Web page. Jsfiddle all the code is modifiable. I deliberately operate at random. You can try to get the opposite result several times. It can be directly extended to multiple promise chains, just like the previous Nodejs examples.

Parallel promises

Consider one asynchronous operation feeding another asynchronous operation. Let the latter include three parallel asynchronous behaviors, which, in turn, feed the last action. It can only be passed if all parallel child requests are passed. This is inspired by a dozen MongoDB operations. Some are qualified for parallel operations. I realized the promises flow diagram.

How do we simulate those parallel promises in the center line of the diagram? The key is that the largest promise library has a full feature that produces a parent promie that contains a set of child promises. When all the children promises through, the Father promise through. If there is a child promise refused, the parent promise refuses.

Let 10 parallel promises each contain a text promise. The last then method can be completed only if 10 subclasses pass or if any subclass rejects it.

Figure

var promisevals = [' to ', ' Being, ', ' or ', ' not
  ', ' to ', ' Being, ', ' that ',
  ' is ', ' the ', ' question '];
 
var startparallelactions = function () {
  var promises = [];
 
  Make a asynchronous action from each literal
  promisevals.foreach (function (value) {
    Promises.push ( Makeapromise (value));
 
  Consolidate all promises to a promise of promises return
  Q.all (promises);
 
Startparallelactions (). Then (...).

The following address, http://jsfiddle.net/mauget/XKCy2/, runs 10 parallel promises in the browser for Jsfiddle, randomly rejecting or passing. Here is the complete code for checking and changing if conditions. Rerun until you get a reverse finish.

Pregnant Promise

Many APIs return promise have a then function-they are thenable. Usually I just deal with the results of thenable functions through then. However, $q, Mpromise, and Kew libraries have the same APIs for creating, rejecting, or passing promise. Here are the API documents linked to the references section of each library. I don't usually need to construct a promise, except for the promise description and timeout functions of the wrapper in this article. Please refer to which promises I created.

Promise Library Interop

Most JavaScript promise libraries interoperate at the then level. You can create a promise from an external promise, because promise can wrap any type of value. Then can support cross library work. In addition to then, other promise functions may be different. If you need a function that your library does not contain, you can wrap a promise based on your library into a new one, based on a library of promise that contains the functions you need. For example, jquery's promise are sometimes criticized. Then you can wrap it in the Q, $q, mpromise, or promise of the Kew library.

Conclusion

Now I have written this article, and a year ago I hesitated to hug the promise. I simply want to finish a job. I don't want to learn a new API or break my original code (because I misunderstood promise). I used to think so wrongly! When I made a note, it was easy to win the gratifying results.

In this article, I have simply given a single promise,promise chain, and an example of a parallel promise promise. Promises is not difficult to use. If I can use them, anyone can. To view the complete concept, I support you by clicking on the Reference guide written by the expert. Start with the promises/a reference, starting with the promise of the de facto standard JavaScript.

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.