Executing asynchronous calls in a synchronous manner


Question

I've been trying to wrap my head around this issue for the last hours but can't figure it out. I guess I still have to get used to the functional programming style ;)

I wrote a recursive function that traverses through a directory structure and does things to certain files. This functions uses the asynchronous IO methods. Now I want to perform some action when this whole traversing is done.

How would I make sure that this action is performed after all parse calls have been performed but still use the asynchronous IO functions?

var fs = require('fs'),
    path = require('path');

function parse(dir) {
    fs.readdir(dir, function (err, files) {
        if (err) {
            console.error(err);
        } else {                
            // f = filename, p = path
            var each = function (f, p) {
                return function (err, stats) {
                    if (err) {
                        console.error(err);
                    } else {
                        if (stats.isDirectory()) {
                            parse(p);
                        } else if (stats.isFile()) {
                            // do some stuff
                        }
                    }
                };
            };

            var i;
            for (i = 0; i < files.length; i++) {
                var f = files[i];
                var p = path.join(dir, f);
                fs.stat(p, each(f, p));
            }
        }
    });
}

parse('.');

// do some stuff here when async parse completely finished
1
30
7/10/2014 6:04:31 PM

Accepted Answer

Look for Step module. It can chain asynchronous functions calls and pass results from one to another.

12
5/10/2011 2:19:46 PM

You could use async module . Its auto function is awesome . If you have function A() and function B() and function C() . Both function B() and C() depend of function A() that is using value return from function A() . using async module function you could make sure that function B and C will execute only when function A execution is completed .

Ref : https://github.com/caolan/async

async.auto({
            A: functionA(){//code here },
            B: ['A',functionB(){//code here }],
            C: ['A',functionC(){//code here }],
            D: [ 'B','C',functionD(){//code here }]
        }, function (err, results) {
              //results is an array that contains the results of all the function defined and executed by async module
              // if there is an error executing any of the function defined in the async then error will be sent to err  and as soon as err will be produced execution of other function will be terminated
            }
        })
    });

In above example functionB and functionC will execute together once function A execution will be completed . Thus functionB and functionC will be executed simultaneously

functionB: ['A',functionB(){//code here }]

In above line we are passing value return by functionA using 'A'

and functionD will be executed only when functionB and functionC execution will be completed .

if there will be error in any function , then execution of other function will be terminated and below function will be executed .where you could write your logic of success and failure .

function (err, results) {}

On succesfull execution of all function "results" will contain the result of all the functions defined in async.auto

function (err, results) {}

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon