Async: “超出最大调用堆栈大小”使用 async.forEachLimit

创建于 2011-12-26  ·  15评论  ·  资料来源: caolan/async

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);
});

日志

$ 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

最有用的评论

我正在做一个同步操作。 我通过更改来修复它:

callback();

setTimeout(callback, 0);

所有15条评论

forEachLimit看起来不对。

started += 1 running += 1

应该移到迭代器调用的前面。 arr[started]也应该改为arr[started - 1]

注意:只有在迭代器迭代器中的代码在同一滴答中调用回调时,您才会遇到此错误。

停止在 async.js 中调用 SYNC 函数

当我的迭代器中有条件return callback(null);时,我遇到了这个问题。 这意味着我必须做更聪明的事情,即在应用async.forEach Array.filter过滤数组,所以它实际上有点帮助......

如果你_真的_认为你应该这样做,你可以使用process.nextTick(function() { callback(); })来解决这个问题。

@jacobrask效果很好。 谢谢

执行callback(null);是同步的。 您需要异步调用它,ala process.nextTick(callback)process.nextTick(function() { callback(null); }); 。 就像@bobrik说的,停止在异步中调用同步函数:)

说“停止在异步中调用同步函数”没有抓住重点——它被破坏了,而且只有在 forEachLimit 中这似乎是一个问题。

async.forEachLimit(['a','b'], 1, function(item, callback){
  if(something) {
    doStuff(function(){ callback(); });
  } else {
    callback();
  }
});

虽然我可以很容易地防止这个非常具体的例子(正如@jacobrask通过过滤提到的那样),但如果 doStuff()(可能在我无法控制的库中)决定在没有 process.nextTick() 的情况下调用我的回调呢?

我添加了一些代码来调用 async.nextTick 如果它检测到一个同步迭代器,在这些情况下应该避免堆栈溢出。 但说真的,停止异步调用同步函数! ...使您的函数始终同步或始终异步;)

这也发生在我身上async.eachSeries

也发生在mapLimit ,是的,我的函数是同步的,因为它是一个模拟函数。 然后我把它包在setImmediate中,问题就解决了。

发生在我身上async.forEachOfLimit

面临与async.waterfall相同的问题。

当然,async.queue 也是如此。

我正在做一个同步操作。 我通过更改来修复它:

callback();

setTimeout(callback, 0);

当我有一个与承诺相关的问题时,这发生在我身上。 就像是:
async.forEach(items, (item:any, callback:Function) => { someAsyncPromise(item).then(() => { callback(); }).catch((err) => { //console error or something here callback(); }) });

catch 必须在 Promise 中的 async 位之前抛出,因为只有在 Promise 中发生异常时才会抛出此错误。

`

我知道我们应该停止异步调用同步函数。

但是,如果在异步主体中调用同步函数 callback() 是错误的,为什么异步文档会在示例中显示这一点?

有人可以帮我理解使用异步模块的“正确”方式是什么吗?

这是直接来自异步文档的示例:

// 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

谢谢!

此页面是否有帮助?
0 / 5 - 0 等级