node. JS Programming Async

Source: Internet
Author: User
Tags readfile

Asynchronous operation

Node uses the V8 engine to process JavaScript scripts, with the biggest feature being single-threaded runs and running only one task at a time. This causes node to take a large number of asynchronous operations (asynchronous Opertion), that is, the task is not executed immediately, but is inserted at the end of the task queue until the previous task is run and executed.

Due to this feature, the subsequent operation of a task is often defined in the form of a callback function (callback).

var function (value, callback) {  iftrue) {    callback (null, "value was true.") );  }   Else {    callback (new Error ("Value is not true!" ));  }}

The above code will take further processing to the callback function callback.

If no error occurs, the first parameter of the callback function is passed to null. This writing has a great advantage, that is, as long as you judge the first parameter of the callback function, you know there is no error, if not NULL, it must be wrong. In addition, this can also pass errors at layers.

Node Convention, if a function requires a callback function as a parameter, the callback function is the last parameter. In addition, the first parameter of the callback function itself, the convention is the error object passed in the previous step.

var function (Error, value) {  if  (error) {    return  console.log (Error);  }  Console.log (value);}
The challenges of asynchronous development

When you create an asynchronous program, you have to keep a close eye on the program's execution process and focus on the state of the program: The condition of the event rotation, the program variables, and other resources that have changed as the program's logic executes. If you are not careful, the variables of the program may also change unexpectedly. The following code is a piece of asynchronous code that causes confusion because of the order of execution.

If the code in the example can be executed synchronously, it is certain that the output should be "The color is blue", but this example is asynchronous, and the value of color before console.log execution is still changing, so the output is "The color is green".

function Asyncfunction (callback) {  $)  }var color = ' Blue 'asyncfunction (  function() {  console.log (' The color is ' + color)  = ' green '

With JavaScript closures you can "freeze" the value of color, and in the following code, the call to Asyncfunction is encapsulated in an anonymous function with the color parameter, so that the anonymous function can be executed immediately, passing the value of the current color to it. Color becomes the parameter of the anonymous function, which is the local variable inside the anonymous function, and the local version of color is unaffected when the color value outside the anonymous function changes.

function Asyncfunction (callback) {  $)  }var color = ' Blue '(function (color) {  asyncfunction(function() {    console.log (' The color is ' + color)  // The color is blue.    = ' Green

This is just one of many JavaScript programming techniques that need to be used in node development.

Now that we know how to use the state of the closure control program, let's look at how to make the asynchronous logical sequence execute.

Sequencing of asynchronous processes

The concept of having a set of asynchronous task sequences executed is referred to as Process Control by the node community. This control is divided into two categories: serial and parallel,

When to use serial process Control

You can use callbacks to let several asynchronous tasks execute sequentially, but if you have a lot of tasks, you have to organize them, or you'll get stuck in a callback hell.

The following code is a callback for the task order execution.

SetTimeout (function() {   console.log (' I execute first. ') )   setTimeout (function() {      console.log (' I execute next. ') )      setTimeout (function() {         console.log (' I execute last. ')       )   1000)    

In addition, you can use a Process control tool such as promise to execute the code

Promise.then (function(Result) {//dosomething        returnresult; }). Then (function(Result) {//dosomething        returnpromise1; }). Then (function(Result) {//dosomething}).Catch(function(ex) {Console.log (ex); }).finally(function() {Console.log ("Final"); });

We then use examples to achieve serialization process control and parallelization of Process Control.

Enables serialization of process control

In order to have several asynchronous tasks executed sequentially with serialization process control, these tasks need to be placed in an array in the desired order of execution. As shown in the following:

The following is a serialization Process Control demo, implemented from a randomly selected RSS feed to get an article title and URL, source files

//serialization of Process Control in a simple programvarFS = require (' FS ')varRequest = require (' request ')//use it to get RSS datavarHtmlparser = require (' Htmlparser ')//Convert raw RSS data into JavaScript architecturevarConfigfilename = './rss_feeds.txt 'functionCheckforrssfile () {//Task 1: Make sure that a file that contains a list of RSS pre-source URLs existsFs.exists (Configfilename,function(exists) {if(!exists) {      returnNextNewError (' Missing RSS file: ' + configfilename))//return as soon as you have an error} next (NULL, Configfilename)})}functionReadrssfile (configfilename) {//Task 2: Read and parse a file containing a predetermined source URLFs.readfile (Configfilename,function(Err, feedlist) {if(err) {returnNext (Err)} feedlist= Feedlist//the list of predetermined source URLs is converted into a string and then separated into an array. toString (). Replace (/^\s+|\s+$/g, "). Split ("\ n"); varRandom = Math.floor (Math.random () *feedlist.length)//randomly select a predetermined source URL from an array of predetermined source URLsNextNULL, Feedlist[random])})}//console.log (' Enter ')functionDownloadrssfeed (Feedurl) {//Task 3: Send an HTTP request to the selected scheduled source for dataRequest ({Uri:feedurl},function(err, res, body) {if(err) {returnNext (Err)}if(Res.statuscode! = 200) {      returnNextNewError (' Abnormal response status code ') } next (NULL, Body)})}functionParserssfeed (RSS) {//Task 4: Resolve the scheduled source data into an array of entries  varHandler =NewHtmlparser. RssHandler ()varParser =NewHtmlparser. Parser (handler) parser.parsecomplete (RSS)if(!handler.dom.items.length) {returnNextNewError (' No RSS items found ') } console.log (Handler.dom.items)varitem =Handler.dom.items.shift () console.log (item.title) Console.log (item.link)}vartasks = [Checkforrssfile,//Add all the tasks you want to do to an array in order of executionReadrssfile, Downloadrssfeed, Parserssfeed]functionNext (err, result) {if(err) {ThrowErr}varCurrenttask = Tasks.shift ()//remove the next task from the task array  if(currenttask) {currenttask (Result)//perform the current task}}next ()//start serialization execution of a task

As shown in this example, serialization process control essentially puts callbacks into place when needed, rather than simply nesting them.

Enables parallelization of Process control

In order for asynchronous tasks to execute in parallel, the task is still put into the array, but the order in which the tasks are placed does not matter. Each task should call the processor function to increase the count value of the completed task. When all tasks are completed, the processor function should perform subsequent logic.

Take a look at a small demo of the parallelization Process Control, which enables statistics to print out the total number of words that appear in the console, respectively. source file

//implement parallel Process Control in a simple programvarFS = require (' FS ')varCompletedtasks = 0vartasks = []varWordcounts = {}varFilesdir = './text 'functionCheckifcomplete () {//when all tasks are complete, list each word used in the file and how many timescompletedtasks++//Console.log (completedtasks)Console.log (tasks.length)if(Completedtasks = =tasks.length) { for(varIndexinchwordcounts) {Console.log (Index+ ': ' +Wordcounts[index])} }}functionCountwordsintext (text) {varWords =text. toString (). toLowerCase (). Split (/\w+/). Sort () for(varIndexinchwords) {//count the words that appear in the text    varWord =Words[index]if(Word) {Wordcounts[word]= (Wordcounts[word])? Wordcounts[word] + 1:1}}}fs.readdir (Filesdir,function(Err, files) {//Get A list of files in the text directory  if(err) {ThrowErr} for(varIndexinchfiles) {    varTask = (function(file) {//defines the task that processes each file, and each task invokes a function that asynchronously reads the file and counts the words used in the file      return function() {fs.readfile (file,function(Err, text) {//note here that Fs.readfile () is an asynchronous process, Countwordsintext (), and the Checkifcomplete () method is followed by the Tasks.push () method          if(err) {ThrowErr} countwordsintext (text) Checkifcomplete ()})}) (Filesdir+ '/' +Files[index]) Tasks.push (Task)} for(varTaskinchtasks) {Tasks[task] ()}})

As above two demos describes the underlying mechanism for serial and parallelization process control.

Summarize

You can manage asynchronous logic with callbacks, event emitters, and process controls. Callbacks are used for one-time asynchronous logic, and event emitters are useful for organizing asynchronous logic, because they can associate asynchronous logic with a conceptual entity, which can be easily managed by the listener, and process control can manage the order of execution of asynchronous tasks, allowing them to be executed one after the other or synchronously. You can implement process management yourself, but community add-ons can help you solve this problem. The choice of which process controls the add-on module is largely dependent on personal preferences and the needs of the project or design.

node. JS Programming Async

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.