async.js每个都在迭代器中得到索引

Kev*_*vin 34 javascript asynchronous node-async

我正在使用caolan的async.js库,特别是.each方法.

如何访问迭代器中的索引?

async.each(ary, function(element, callback){
  //do stuff here for each element in ary
  //how do I get access to the index?
}, function(err) {
  //final callback here
})
Run Code Online (Sandbox Code Playgroud)

xua*_*nji 37

您可以使用async.forEachOf- 它将索引作为其第二个参数调用其迭代器回调.

> async.forEachOf(['a', 'b', 'c'], function () {console.log(arguments)});
{ '0': 'a', '1': 0, '2': [Function] }
{ '0': 'b', '1': 1, '2': [Function] }
{ '0': 'c', '1': 2, '2': [Function] }
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅文档

  • 这应该是公认的答案.目前的答案已经过时. (7认同)

Bas*_*sic 36

更新

自写这个答案以来,现在有一个更好的解决方案.有关详细信息,请参阅xuanji的答案

原版的

感谢@genexp在下面的评论中提供简单明了的例子......

async.each(someArray, function(item, done){
    console.log(someArray.indexOf(item));
});
Run Code Online (Sandbox Code Playgroud)

阅读完文档后,我怀疑没有办法访问表示列表中位置的整数...

将迭代器函数并行应用于数组中的每个项目.使用列表中的项目调用迭代器,并在完成时调用它.如果迭代器将错误传递给此回调,则会立即调用每个函数的主回调并显示错误.

注意,由于此函数并行地将迭代器应用于每个项目,因此无法保证迭代器函数将按顺序完成.

所以我挖得更深一点(源代码链接)

async.each = function (arr, iterator, callback) {
        callback = callback || function () {};
        if (!arr.length) {
            return callback();
        }
        var completed = 0;
        _each(arr, function (x) {
            iterator(x, only_once(function (err) {
                if (err) {
                    callback(err);
                    callback = function () {};
                }
                else {
                    completed += 1;
                    if (completed >= arr.length) {
                        callback(null);
                    }
                }
            }));
        });
    };
Run Code Online (Sandbox Code Playgroud)

正如您所看到的那样,有一个completed计数在每个回调完成时更新,但没有实际的索引位置.

顺便说一句,更新completed计数器的竞争条件没有问题,因为JavaScript 完全是单线程的.

编辑:在深入挖掘迭代器之后,看起来你可以通过index闭包来引用一个变量......

async.iterator = function (tasks) {
    var makeCallback = function (index) {
        var fn = function () {
            if (tasks.length) {
                tasks[index].apply(null, arguments);
            }
            return fn.next();
        };
        fn.next = function () {
            return (index < tasks.length - 1) ? makeCallback(index + 1): null;
        };
        return fn;
    };
    return makeCallback(0);
};
Run Code Online (Sandbox Code Playgroud)

  • 我想在这里总结一下,答案是"不"你不能,这很烦人,但也是由于默认情况下每个并行化的方式设计.但是,由于封闭的魔力,你可以访问你的原始数组,所以这样的东西应该工作:`async.each(someArray,function(item,done){console.log(someArray.indexOf(item)); });` (19认同)

Ala*_*ois 9

只是用async.forEachOf().

async.forEachOf(arr, function(value, index, callback) { ... }, ...
Run Code Online (Sandbox Code Playgroud)

有关详情,请参阅此处的文档.