In-depth analysis of node. js concurrent asynchronous callback processing _ node. js

Source: Internet
Author: User
This article mainly introduces node. js concurrent asynchronous callback processing related information. If you need a friend, you can refer to this article to say that concurrent Asynchronous is not accurate. It should be said that continuous asynchronous. The single-thread asynchronous feature of NodeJs directly leads to multiple asynchronous simultaneous calls, and the final execution result cannot be determined for back-and-forth calls. A simple example:

for(var i = 0; i < 5; i++) {  fs.readFile('file', 'utf-8', function(error, data){});} 

It is very easy to initiate an asynchronous operation to read files five times in a row. The question is, how can I determine that all asynchronous operations have been completed? Because the subsequent operations can only be performed after they are all executed. I believe that some experienced students will think of using the notation, but how to ensure the correctness of the notation is a problem. Think about it:

A callback is a function. During each asynchronous operation, the counter is + 1. When each asynchronous operation ends, the counter is-1, and whether the counter is 0 is determined to execute the callback. This logic is very simple. A global variable relative to the execution time and the callback time is used as the counter, and the operation of + 1 must be executed in the asynchronous method, and a function for callback will be returned later, it's a bit difficult, but let's look at the advanced usage of Js functions:

Var pending = (function () {var count = 0; return function () {count ++; return function () {count --; if (count = 0) {// All execution completed }}}});

When pending is called, it is pending (), for example:

var done = pending(); 

In this case, the count variable is initialized to 0, and the returned function is attached to done. What will happen if you execute done? Whether to directly execute the first function returned by pending, namely: pending (). What is this execution? First, return the count variable count + 1 and a function, this function is directly passed as a callback method to an Asynchronous Method. When this callback is executed, the count variable count-1 is first used to determine whether the count is 0, if it is set to 0, all asynchronous operations are completed, so as to achieve continuous Asynchronization and the same callback operation.

The key lies in two return statements:

The first return function is to count + 1, and then return the function to be called back.

The second return function is the function that needs to be called back. If it is executed, it will count-1, and then judge whether the asynchronous operation is complete. After the execution is complete, it will call back.

Let's take a look at the actual example and read the asynchronous callback of multiple files:

var fileName = ['1.html', '2.html', '3.html'];var done = pending(function(fileData) {  console.log('done');  console.log(fielData);});for(var i = 0; i < fileName.lenght; i++) {  fs.readFile(fileName[i], 'utf-8', done(fileName[i]));}

In the done, the pending method is used to package the method we want to call back for execution. When the counter is 0, it will be executed. Then we need to improve the pending method:

var pending = (function(callback) {  var count = 0;  var returns = {};  console.log(count);  return function(key) {    count++;    console.log(count);    return function(error, data) {      count--;      console.log(count);      returns[key] = data;      if (count === 0) {        callback(returns);      }    }  }}); 

Callback is our callback function. When var done = pending (callback), done is actually the first return function. It has a parameter that can be used as the subscript of the returned value, therefore, in the loop body done (fileName [I]), the file name is passed in. This done () is executed directly. After count + 1 is executed, it returns the callback function to be passed to the Asynchronous Method. As mentioned above, this callback function determines whether to execute the callback function based on the counting variable, and passes the file content to it, that is, returns. Now, run the command to see the running result accurately.

0
1
2
3
2
1
0
Done
{"1.html": "xxx", "2.html": "xxx", "3.html": "xxx "}

From the display on the count, we can see that from 0-3 to 0, then our callback function outputs The done and file content.

If this problem is solved, we need to think about how to reuse such a method. Otherwise, isn't it unscientific to write pending every time?

Next let's take a look at the processing method of UnJs (My NodeJs-based Web development framework), which is applied to subtemplate operations in template parsing:

unjs.asyncSeries = function(task, func, callback) {  var taskLen = task.length;  if (taskLen <= 0) {    return;  }  var done = unjs.pending(callback);  for(var i = 0; i < taskLen; i++) {    func(task[i], done);  }} 

AsyncSeries has three parameters, meaning:

Task: the object to be processed. For example, the object to be read is a list. If it is not a list or the list length is 0, it will not be executed.

Func: Asynchronous Method. For example, fs. readFile is passed in through it.

Callback: the method we want to call back

Similar to the previous one, done passed the code to func, but it was not executed. Because you want the application to be able to control parameters, You can execute the code on the application.

Let's take a look at the operations when processing the sub-template:

var subTemplate = [];var patt = /\{\% include \'(.+)\' \%\}/ig;while(sub = patt.exec(data)) {  var subs = sub;  subTemplate.push([subs[0], subs[1]]);}unjs.asyncSeries(subTemplate, function(item, callback) {  fs.readFile('./template/' + item[1], 'utf-8', callback(item[0]));}, function(data) {  for(var key in data) {    html = html.replace(key, data[key]);  }}); 

The subTemplate list is generated based on the parsing of the subTemplate. It is a two-dimensional array. The first value of each subitem is the call text of the subTemplate, that is: {% include 'header.html '%}. The second parameter is the subtemplate file name, that is, header.html.

The second parameter of asyncSeries is callback, which is actually the third parameter, that is, the callback method of the callback function we want to execute after pending processing. As mentioned above, in asyncSeries, it does not run, but is run here, that is: callback (item [0]), with the parameter, this parameter is also used to replace the string that calls the sub-template in the parent template with the content of the corresponding sub-template.

In this way, the asyncSeries method can be used for processing as long as continuous Asynchronization is required. Because of the asynchronous relationship, the process of the program may be a bit difficult to understand. Even if you are familiar with it, you may suddenly fail to understand it. For example, in the second parameter, the callback is actually generated by the third parameter. At first you may wonder what the callback is. There are also two pending return statements, which are not easy to understand and need to be considered.

Now, continuous asynchronous callback is completed using the advanced features of Js functions. However, The Asynchronization of node. js makes program control very problematic, such as continuous Asynchronization, but value-passing operations. These can all be achieved through such ideas, you can change it.

The above content is a small Editor to share with you the node. js concurrent asynchronous callback processing knowledge, I hope you like it.

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.