简体   繁体   中英

Using async module to fire a callback once all files are read

I'm using caolan's 'async' module to open an array of filenames (in this case, template file names).

Per the documentation, I'm using async.forEach() ,so I can fire a callback once all operations have completed.

A simple test case is:

var async = require('async')
var fs = require('fs')

file_names = ['one','two','three'] // all these files actually exist

async.forEach(file_names, 
    function(file_name) {
        console.log(file_name)
        fs.readFile(file_name, function(error, data) {
            if ( error) {   
                console.log('oh no file missing')   
                return error
            } else {
                console.log('woo '+file_name+' found')
            }       
        })
    }, function(error) {
        if ( error) {   
            console.log('oh no errors!')
        } else {
            console.log('YAAAAAAY')
        }
    }
)

The output is as follows:

one
two
three
woo one found
woo two found
woo three found

Ie, it seems the final callback isn't firing. What do I need to do to make the final callback fire?

The function that is being run across all items must take a callback, and pass its results to the callback. See below (I've also separated fileName to improve readability):

var async = require('async')
var fs = require('fs')

var fileNames= ['one','two','three']


// This callback was missing in the question.
var readAFile = function(fileName, callback) {
    console.log(fileName)
    fs.readFile(fileName, function(error, data) {
        if ( error) {   
            console.log('oh no file missing')   
            return callback(error)
        } else {
            console.log('woo '+fileName+' found')
            return callback()
        }       
    })
}

async.forEach(fileNames, readAFile, function(error) {
    if ( error) {   
        console.log('oh no errors!')
    } else {
        console.log('YAAAAAAY')
    }
})

Returns:

one
two
three
woo one found
woo two found
woo three found
YAAAAAAY

This is the best way to do it in my opinion. The results param will have an array of strings containing the file data and all of the files will be read in parallel.

var async = require('async')
    fs    = require('fs');

async.map(['one','two','three'], function(fname,cb) {
  fs.readFile(fname, {encoding:'utf8'}, cb);
}, function(err,results) {
  console.log(err ? err : results);
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM