This is said to be asynchronous, not accurate, should be said to be continuous asynchronous. Nodejs a single-threaded asynchronous feature that directly causes multiple asynchrony to occur simultaneously, unable to determine the final execution result to callback. For a simple example:
for (var i = 0; i < 5; i++) {
fs.readfile (' file ', ' Utf-8 ', function (error, data) {});
5 consecutive asynchronous operations to read files, very simple, so the question is, how can I be sure that all of the asynchronous has been done? Since they are all done, the subsequent operation can be performed. Believe that a bit of experience students will think of using the way of counting, but how to ensure that the correct number is a problem. Think carefully:
The callback is a function that will counter +1 for each asynchronous operation, and when each asynchronous end will counter-1 to determine whether the callback is executed by determining whether the counter is 0来. This logic is simple, requires a global variable relative to the Run-time and callback as a counter, and to pass the asynchronous method is to do +1, and then return a callback function, a bit around, but look at the advanced use of JS function:
var pending = (function () {
var count = 0;
return function () {
count++;
return function () {
count--;
if (count = = 0) {
//all completed
}
}
}
When pending calls, that is, pending (), for example:
The count variable count is initialized to 0, and the returned function is attached to the done, what if done ()? is not directly executing the first function returned by pending, namely: Pending () (), what is this execution, first the count variable count+1, and return a function, this function directly as callback to the asynchronous method, when the implementation of this callback , the first is to count-1 the count variable to determine whether count is 0, and if 0 means that all asynchronous execution is complete, thus achieving a continuous asynchronous, same callback operation.
The key is on the two return, simply said:
The first return function is to count+1, and then returns the function that requires a callback.
The second return function is the function that needs a callback, and if it executes, it will count-1, and then determine whether the asynchronous execution is complete, and then the callback
To see an example of an actual point, an asynchronous callback that reads multiple files:
var fileName = [' 1.html ', ' 2.html ', ' 3.html '];
var = 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));
}
One of the done, that is, using the pending method to wrap up the method we want to callback execution, when the counter is 0 o'clock, we will execute it, then we have 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 does = Pending (callback), the done is actually the first return function, it has a parameter, can be used as the subscript of the returned value, so done in the loop Body (filename[i)) , and the name of the file was passed in. This done () is executed directly, it will count+1, returns the callback function to pass to the asynchronous method, as mentioned above, the callback function will judge whether to execute the callback function we want to execute according to the counting variable, and pass the contents of the file to it, namely returns. OK, run it, I believe I can see the results of the operation accurately.
0
1
2
3
2
1
0
Done
{"1.html": "xxx", "2.html": "xxx", "3.html": "XXX"}
It is clear from the count that from 0-3 to 0, then our callback function outputs the done and the contents of the file.
This problem solved, we have to think about, how to let this method encapsulation reuse, otherwise, every time write pending is not very unscientific?
Take a look at the way Unjs (my Nodejs Web development framework) is handled and applied to the child template operations in template resolution:
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: An object that needs to be processed, such as a file that needs to be read, a list, if it is not a list, or if the list length is 0, it will not perform
Func: Asynchronous methods, such as Fs.readfile, are passed through it.
Callback: The way we want the callback
Done and in the same way, it passed to the Func, but did not execute, because you want the application to be able to control the parameters, so let the application side to execute.
Look at the operation of the child 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]);
}
Subtemplate This list is the data generated from the parsing of the template, which is a two-dimensional array, with the first value of each subkey being the calling text of the child template, namely: {% include ' header.html '%} string, the second parameter is the child template file name, namely: header.html
The second parameter of Asyncseries is callback, which is actually the third parameter, which is the callback method that we want to execute through the pending process, as we said earlier, inside the asyncseries, it's not running, it's running here, That is: Callback (Item[0]), with parameters, because it is also followed by this parameter to replace the string that calls the child template in the parent template with the contents of the corresponding child template.
This way, you can use the Asyncseries method as long as you need a continuous asynchronous process. Because of the asynchronous relationship, the process of the program is a bit around, may start not very good understanding, even if familiar with, may suddenly want to not understand, it doesn't matter, for example, the second parameter in the callback is actually the third parameter generated, at the beginning you may think, this callback is what. There is the pending two return, is not very good understanding, need to think more.
OK, the continuous asynchronous callback is done using the advanced features of the JS function. But the nodejs of the asynchronous nature of the program control is very problematic, such as there is a continuous asynchronous, but to the operation of the value, these can be through such ideas, changes can be achieved.
The above content is small to share the Nodejs concurrent asynchronous callback processing of the relevant knowledge, I hope you like.