Search code examples
javascriptnode.jsasynchronousasync.jsnode-async

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

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


Solution

  • 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