Home > Web Front-end > JS Tutorial > body text

JavaScript asynchronous programming: specific methods of asynchronous data collection_javascript skills

WBOY
Release: 2016-05-16 17:25:13
Original
1035 people have browsed it

Asyncjs/seriesByHand.js

Copy code The code is as follows:

var fs = require('fs');
process.chdir('recipes'); // Change working directory
var concatenation = '';

fs.readdir('.', function(err, filenames) {
if (err) throw err;

function readFileAt(i) {
var filename = filenames[i];
fs.stat(filename, function(err, stats) {
if (err) throw err;
if (! stats.isFile()) return readFileAt(i 1);

fs.readFile(filename, 'utf8', function(err, text) {
if (err) throw err;
concatenation = text;
if (i 1 === filenames.length ) {
                                                                                                                                                                                                                                                                       ’ to ’ never ’ to ’   never to ’  });
}
readFileAt(0);
});




As you can see, the asynchronous version has a lot more code than the synchronous version. If you use synchronous methods such as filter and forEach, the number of lines of code is only about half, and it is much easier to read. How nice it would be if there were asynchronous versions of these nifty iterators! Use Async.js to do just that!

When is it okay to throw it out?

You may have noticed that in the above code example, the author ignored the advice I gave in Section 1.4: throwing exceptions from callbacks is a bad design, especially in a production environment. However, there is no problem with a simple example that throws an exception directly. If an unexpected error occurs in your code, throw will shut down the code and provide a nice stack trace explaining the cause of the error.

What’s really wrong here is that the same error handling logic (i.e. if(err) throw err) is repeated as many as 3 times! In Section 4.2.2, we'll see how Async.js can help reduce this duplication.

Functional writing method of Async.js

We want to replace the filter and forEach methods used by synchronous iterators with corresponding asynchronous methods. Async.js gives us two options.

async.filter and async.forEach, which process the given array in parallel.

async.filterSeries and async.forEachSeries, they will process the given array sequentially.

Running these asynchronous operations in parallel should be faster, so why use a sequential approach? There are two reasons.

The previously mentioned problem of unpredictable workflow order. We can indeed store the results into an array first, and then join the array to solve this problem, but this is one more step after all.

There is an upper limit on the number of files that Node and any other application process can read simultaneously. If this upper limit is exceeded, the operating system will report an error. If you can read the file sequentially, you don't need to worry about this limitation.
So now let’s understand async.forEachSeries first. The data collection method of Async.js is used below, and the code implementation of the synchronous version is directly rewritten.

Asyncjs/forEachSeries.js



Copy code

The code is as follows:var async = require('async');var fs = require('fs');process.chdir('recipes'); // Change the working directory
var concatenation = '';

var dirContents = fs.readdirSync('.');

async.filter(dirContents, isFilename, function(filenames) {
async.forEachSeries(filenames, readAndConcat, onComplete);});

function isFilename(filename, callback) {

fs.stat(filename, function(err, stats) {
if (err) throw err;
callback(stats.isFile());

});

}

function readAndConcat(filename, callback) {
fs.readFile(filename, 'utf8', function(err, fileContents) {
if (err) return callback(err);
concatenation = fileContents ;

callback();

});
}

function onComplete(err) {
if (err) throw err;
console.log(concatenation);
}


Now our code is beautifully divided into two parts: task overview (in the form of async.filter call and async.forEachSeries call) and implementation details (in the form of two iterator functions and a completion callback onComplete).

filter and forEach are not the only Async.js utility functions that correspond to standard functional iteration methods. Async.js also provides the following methods:

reject/rejectSeries, just the opposite of filter;
map/mapSeries, 1:1 transformation;
reduce/reduceRight, the gradual transformation of values;
detect/detectSeries, find the value matching the filter;
sortBy, produces an ordered copy;
some, tests whether at least one value meets the given criteria;
every, tests whether all values ​​meet the given criteria.
These methods are the essence of Async.js, allowing you to perform common iterative work with minimal code duplication. Before continuing to explore more advanced methods, let's look at error handling techniques for these methods.

Async.js error handling technology
If you want to blame it, blame Node’s fs.exists for being the first to do this! And this also means that iterators that use Async.js data collection methods (filter/filterSeries, reject/rejectSeries, detect/detectSeries, some, every, etc.) cannot report errors.

For all Async.js iterators that are not boolean, passing a non-null/undefined value as the first parameter of the iterator callback will immediately call the completion callback with the error value. This is why readAndConcat works without throw.

Asyncjs/forEachSeries.js

Copy code The code is as follows:

function readAndConcat(filename, callback) {
fs .readFile(filename, 'utf8', function(err, fileContents) {
if (err) return callback(err);
concatenation = fileContents;
callback();
});
}

So, if callback(err) is indeed called in readAndConcat, this err will be passed to the completion callback (ie onComplete). Async.js is only responsible for ensuring that onComplete is called only once, regardless of whether it is called because of the first error or when all operations are successfully completed.

Asyncjs/forEachSeries.js

Copy code The code is as follows:

function onComplete(err) {
if (err ) throw err;
console.log(concatenation);
}

Node’s error handling convention may not be ideal for Async.js data collection methods, but for Async. As with all other methods in js, adhering to these conventions allows errors to flow cleanly from each task to the completion callback. We'll see more examples of this in the next section.
Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template