Nodejs Learning Notes-Asynchronous programming solutions

Source: Internet
Author: User
Tags emit readfile

In JS or node programming, due to the frequent and extensive use of asynchronous, so that the callback and nesting depth caused by the experience of programming encountered some challenges, if you write elegant and good-looking code, this article mainly for asynchronous programming mainstream program to do some summary

1. Event Publish/Subscribe mode

Event Listener mode is a widely used mode for asynchronous programming, is the event of callback function, also known as the Publish/Subscribe mode, node itself provides the events module, is a simple implementation of the pattern.

Eventporxy

2. PROMISE/DEFERRD mode

In 2009, Kris Zyp was abstracted as a draft proposal, published in the COMMONJS specification, and currently, the COMMONJS draft includes PROMISE/A, Promise/b, and promise/d asynchronous models. Because the promise/a is more commonly used is also relatively simple, only need to have then () method. So first introduce some of the change mode.

In general, the then () method is defined as follows:

Then (Fulfilledhandler, ErrorHandler, Progresshandler)
promises/a

By inheriting node's events module, we can implement a simple promise module.

Promise part

var Promise = function () {    eventemitter.call (this);} Util.inherits (Promise, Eventemitter); Util is the tool class with node Promise.prototype.then = function (Fulfilledhandler, ErrorHandler, Progresshandler) {    if (typeof Fulfilledhandler = = = "function") {        this.once (' success ', Fulfilledhandler);    }    if (typeof ErrorHandler = = = "function") {        this.once (' Error ', ErrorHandler);    }    if (typeof Progresshandler = = = "function") {        This.on (' Progress ', Progresshandler);    }    

Deferred part

var Deferred = function () {    this.state = ' unfulfilled ';    This.promise = new Promise ();} Deferred.prototype.resolve = function (obj) {    this.state = ' fulfilled ';    This.promise.emit (' success ', obj);} Deferred.prototype.reject = function (obj) {    this.state = ' failed ';    This.promise.emit (' error ', obj);} Deferred.prototype.progress = function (obj) {    this.promise.emit (' Progress ', obj);}

Use

function readFile (file, encoding) {      var deferred = new deferred ();      Fs.readfile (file, encoding, deferred.resolve);      return deferred.promise;} ReadFile ('/test.txt ',  ' Utf-8 '). Then (function (data) {      ...}, function (err) {      ...});    

The above is a simple implementation of the promise/deferred pattern, which can be described in the state transition diagram:

The promise mode is slightly more elegant than the Publish/subscribe model, but it does not meet the real needs of many scenarios, such as a set of purely asynchronous APIs to work together to complete a string of things.

promises/a+

The specification clarifies the recommendations of the previous PROMISES/A specification for the standard of conduct. It extends the original specification to cover some of the customary behavior, and omits some parts that exist only in certain situations or that have problems.

See: Chinese version: http://www.ituring.com.cn/article/66566, English version: https://promisesaplus.com/

3. Process Control repository tail trigger and next

Tail trigger is currently the most widely used in the middleware of Connect, middleware processing network requests, can be used for cutting-oriented programming, such as filtering, verification, logging and other functions, the simplest middleware is as follows:

Function (req, res, next) {     //middleware      }

Each middleware passes the request object, the response object, and the tail trigger function, forming a processing stream through the queue as follows:

  

See an example

App.use (function (req, res, next) {    setTimeout (function () {        next ();     }, 0)}, function (req, res, next) {    SetTimeout (function () {         next ();     }, 0);});

From this example, we can easily guess the implementation principle of the tail trigger, simply by invoking use to maintain a queue, call next when the team out and execute, loop in turn.

Async

Currently the most well-known Process Control module, Async module provides more than 20 methods for handling asynchronous multiple writing modes, such as:

1. Asynchronous Serial execution

Async.series ([    function (callback) {        //do some stuff ...        Callback (NULL, ' one ');    },    function (callback) {        //do some more stuff ...        Callback (NULL, ' both ');    }],//Optional callbackfunction (err, results) {    //results is now equal to [' One ', ' both ']}) ;

An example using a object instead of an arrayAsync.Series({One:function(Callback){SetTimeout(function(){Callback(Null,1); 200}, twofunction ( callback) {settimeout ( Function () {callback (null2); 100}},function (err results) {//results Equal to: {one:1, Two:2}              

The exception handling principle is the first parameter that encounters an exception that ends all calls and passes an exception to the final callback function

2. Asynchronous Parallel execution

An example using a object instead of an arrayasync.parallel ({    one:function (callback) {        setTimeout (function () {            callback (null, 1);        },    two:function (callback) {        setTimeout (function () {            callback (null, 2);        },    }},function (err, results) {    //results is today equals to: {one:1, two:2}});

Unlike Eventproxy-based event publishing and subscription patterns, which are used by callback functions, async callback functions are passed in by async, and Eventproxy uses the Done (), fail () method to generate a new callback function, which is the application of higher-order functions.

3. Dependency processing of asynchronous calls

Async.waterfall ([    function (callback) {        callback (null, ' One ', ' both ')    ,    function (arg1, arg2,  Callback) {      //arg1 now equals ' one ' and arg2 now equals ' both '        callback (NULL, ' three ');    },    function (Arg1, Callback) {        //arg1 now equals ' three '        callback (null, ' done ');    }], function (err, result) {   //Result No W equals ' Done '    });

4. Automatic Dependency processing

Async.auto ({get_data:function (callback) {Console.log (' in Get_data ');    Async code to get some data callback (NULL, ' data ', ' converted to array ');        }, Make_folder:function (callback) {Console.log (' in Make_folder '); Async code to create a directory to store a file in//This is run at the same time as getting the data C    Allback (null, ' folder '); }, Write_file: [' get_data ', ' Make_folder ', function (callback, results) {Console.log (' in Write_file ', json.string        Ify (results)); Once there is some data and the directory exists,//write the data to a file in the directory callback (n    ull, ' filename '); }], Email_link: [' Write_file ', function (callback, results) {Console.log (' in Email_link ', json.stringify (results)        ); Once the file is written let's email a link to it ...//Results.write_file contains the filename returned by WRI        Te_file. Callback (NULL, {' file ': Results.wriTe_file, ' email ': ' [email protected] '});    }]}, function (err, results) {console.log (' err = ', err); Console.log (' results = ', results);});

In a real-world business environment, there are many complex dependencies, and synchronization and asynchrony are not deterministic, so the auto method can automatically analyze execution based on dependencies.

Step

The lightweight async is also consistent with API exposure because there is only one interface step.

There are some differences in asynchronous processing, and once the step produces an exception, it will be passed in as the first parameter of the next method.

var s = require (' step '); s (    function readself () {        fs.readfile (__filename, this);    },      function (err, Content) {        //Parallel execution        of task Fs.readfile (__filename, This.parallel ());        Fs.readfile (__filename, This.parallel ());    },      function () {
Task group Save result var group = This.group (); Console.log (arguments); Fs.readfile (__filename, Group ()); Fs.readfile (__filename, Group ()); }, function () { console.log (arguments); } )
Wind

Pending additions

Summarize

Compare the differences between several scenarios: the event Publish/Subscribe mode is relatively primitive, and the promise/deferred model contributes a very good abstraction of the asynchronous task model, starting with encapsulating the asynchronous invocation part, while the Process Control library is much more flexible.

In addition to async, step, Eventproxy, wind and other programs, there is a class of source code compiled by the scheme to achieve the simplification of the process control, streamline is a typical example.

Reference

The fourth chapter of the Nodejs in layman's

https://promisesaplus.com/

https://github.com/caolan/async/

Https://github.com/creationix/step

http://www.ituring.com.cn/article/66566

Nodejs Learning Notes-Asynchronous programming solutions

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.