首页 > Array 的 forEach 方法是异步的?

Array 的 forEach 方法是异步的?

在 NodeJS 中写了一段数组循环的js代码,发现forEach打印的index值不是从零升序,去 Mozilla 社区查了一下也没说默认是async啊,ES6有这一条吗

打印index如下

2
6
3
8
1
0
5
7
15
4
10
13
11
...

源代码

//返回所有标签
Post.getTags = function(callback) {
  //打开数据库
  MongoClient.connect(connectionString, dbOptions, function(err, db) {
    if (err) {
      return callback(err);
    }
    //读取 posts 集合
    db.collection('posts', function (err, collection) {
      if (err) {
        db.close();
          return callback(err);
        }
      //distinct 用来找出给定键的所有不同值
      collection.distinct("tags", function (err, docs) {
        console.log(docs)
        if (err) {
          db.close();
          return callback(err);
        }
                var list = [];
                docs.forEach(function (val, index) {
                    db.collection('posts', function (err, collection) {
                        if (err) {
                            db.close();
                            return callback(err);
                        }
                        var count = collection.count({
                            "tags" : {
                                "$in" : [val]
                            }
                        }, function (err, total) {
                            var tag = {
                                "tag" : val,
                                "num" : total
                            }
                            list.push(tag);
                            console.log(index);
                            if (index === docs.length) {
                                callback(null, list);
                            }
                        })
                    });
                });
      });
    });
  });
};

docs 的值就是一个数组 ['js', 'css', ...]
缩进粘过来之后乱了,sorry


你在 index 值是在 collection.count 方法的异步回调中完成的, 所以你输出的顺序不是你想要的.
forEach 是顺序执行的, 但你 forEach 内部的代码中 db.collectioncollection.count 应该是异步的, 所以最终输出的时候得到的顺序是不相同的.

你可以把你的代码 list.push(tag); 改为 list[index] = tag; 然后你的 callback 接收到的参数中 list 就是有 doc 拥有相同的顺序了.

但如果这样做, 就需要你用另外一个 计数器, 来保存当前已经回来几个了, 然后和 doc.length 进行比较, 从而决定是否跑完了, 然后执行callback.


你都把打印index的代码放到一个明显是异步的回调函数里了…

【热门文章】
【热门文章】