Jorayen
Jorayen

Reputation: 1971

know when async foreach inside async for each has finished

I'm using the async library in node.js, and I have an async.forEach call inside another async.forEach call and I need to know when the async calls have completely finished processing.

Code example:

var content = '...';
var resultArr = [];

async.each(regexArr, function(regex) {
        var matches = content.match(regex);
        async.each(matches, function(match) {
            var result = regex.exec(match);
            regex.lastIndex = 0;
            resultArr.push(result[1]);
        });
    }, function(err) {
        // I need to know when ALL inner async.forEach finished processing 
        // for ALL outside async.forEach and then do something with the resultArr
    });

Upvotes: 0

Views: 395

Answers (1)

Andrew Templeton
Andrew Templeton

Reputation: 1696

You can force synchronization by using async.map and an additional callback to handle the collection of inner callback results.

ALTHOUGH, with JS, execution is on a single thread, as other people have said, so I've included the MUCH simpler synchronous version first.

// Synchronous version is just as good for Regex stuff.
var content = '...';
var resultArr = [].concat.apply([], regexArr.map(function(regex) {
    return (content.match(regex) || []).map(function(match) {
        return (regex.exec(match) || [])[1];
    });
}));

    // IN THIS EXAMPLE, SYNCHRONOUS WOULD WORK TOO...


    var content = '...';
    collectRegexResults(content, regexArr, function(err, flatRegexResults) {
        // Handle errors.
        // flatRegexResults is equivalent to resultArr
        //    from your question.
    });

    function collectSingleRegexFor(content) {
        return function(regex, passBackGroup) {
            var matches = content.match(regex);
            // Note use of || [] if match is null
            async.map(matches || [], function(match, finishSingle) {
                try {
                    finishSingle(null, regex.exec(match)[1]);
                } catch (err) {
                    finishSingle(err, null);
                }
            }, passBackGroup); // Submits to outer as regexSets element
        };
    }

    function collectRegexResults(text, regexArr, doStuffPostComplete) {
        async.map(regexArr, collectSingleRegexFor(text), function(err, regexSets) {
            if (err) {
                return doStuffPostComplete(err);
            }
            // Flattening the Array again.
            doStuffPostComplete(null, [].concat.apply([], regexSets));
        });
    }

Upvotes: 1

Related Questions