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
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
谢谢!
最有用的评论
我正在做一个同步操作。 我通过更改来修复它:
到