async: 'Maximum call stack size exceeded' using async.forEachLimit

async = require('async');

var documents = ['a', 'b', 'c', 'd', 'e', 'f'];

async.forEachLimit(documents, 2, function(item, callback) {
  console.log(".", item);
  callback(null);
}, function(err){
  console.log("end", err);
});

Log

$ node test.js
. a
. a
. a
. a
. a
. a
end undefined
. b
. b
. b
. b
. b
. b
. b
. b
. b
. b
. b
. b
. b
. b
. b
. b
[...]

node.js:134
        throw e; // process.nextTick error, or 'error' event on first tick
        ^
RangeError: Maximum call stack size exceeded

About this issue

  • Original URL
  • State: closed
  • Created 13 years ago
  • Comments: 15 (1 by maintainers)

Commits related to this issue

Most upvoted comments

I was doing a sync operation. I fixed it by changing from:

callback();

to

setTimeout(callback, 0);

STOP calling SYNC functions in async.js

I understand that we should stop calling sync functions in async.

But, if calling the sync function callback() inside the async body is wrong, why does the async documentation show that in the examples?

Can someone help me understand what is the ‘proper’ way to work with the async module instead?

Here’s an example directly from the async documentation:

// assuming openFiles is an array of file names
async.each(openFiles, function(file, callback) {

    // Perform operation on file here.
    console.log('Processing file ' + file);

    if( file.length > 32 ) {
      console.log('This file name is too long');
      callback('File name too long');
    } else {
      // Do work to process file here
      console.log('File processed');
      callback();
    }
}, function(err) {
    // if any of the file processing produced an error, err would equal that error
    if( err ) {
      // One of the iterations produced an error.
      // All processing will now stop.
      console.log('A file failed to process');
    } else {
      console.log('All files have been processed successfully');
    }
});

https://caolan.github.io/async/docs.html#each

Thanks!

I encountered this problem when I had a conditional return callback(null); in my iterator. It meant I had to do the smarter thing, which is to filter the array using Array.filter before applying async.forEach, so it was actually kind of helpful…

If you really think you should, you can work around this by using process.nextTick(function() { callback(); }).

Doing callback(null); is synchronous. You need to call it asynchronously, ala process.nextTick(callback), or process.nextTick(function() { callback(null); });. Like @bobrik said, stop calling sync functions in async 😃

async.queue, too, of course.

Facing same issue with async.waterfall.

This happened to me when I had a catch attached to a promise. Something like: async.forEach(items, (item:any, callback:Function) => { someAsyncPromise(item).then(() => { callback(); }).catch((err) => { //console error or something here callback(); }) });

catch must be thrown before async bit in promise, because this error thrown only when exception occured in promise.

`