使用 async.each 异步遍历猫鼬集合

Asynchronously loop through the mongoose collection with async.each

本文关键字:集合 遍历 异步 async each 使用      更新时间:2023-09-26

我在我的节点上使用acync.series.js程序。我正在尝试用async.each异步循环猫鼬集合.这是到目前为止的代码:

var async = require('async');
var mongoose = require('mongoose');
var usersData;
async.series([
    function(callback) {
        mongoose.connect("mongodb://localhost/****");
        var db = mongoose.connection;
        db.on('error', console.error.bind(console, 'connection error...'));
        db.once('open', function callback() {
            console.log('db opened!');
        });
        callback();
    },
    function(callback) {
        users = mongoose.model('User', new mongoose.Schema({name: String,age: Number}));
        users.find(function(err, userFound) {
            if (err) {console.log(err);}
            usersData = userFound;
        });
        callback();
    },
    function(callback) {
        async.each(usersData, function(userData, callback) {
            some code....
        }, callback);
    }
])

当我运行它时,我从异步收到以下错误:

    if (!arr.length) {
            ^
TypeError: Cannot read property 'length' of undefined

异步循环猫鼬集合的正确方法是什么

因为async/await将是 ES7 并且已经通过转译非常流行,所以在谷歌搜索猫鼬和异步时,这是一个最重要的结果。

虽然没有回答最初的问题,但我想我会把它留给将来参考。

使用原生承诺(请注意,所有用户都是并行处理的(:

const User = mongoose.model('User', new mongoose.Schema({
  name: String,
  age:  Number
}));

function processUsers() {
  return mongoose.connect('mongodb://localhost')
    .then(function() {
      return User.find();
    })
    .then(function(users) {
      const promises = users.map(function(user) {
        return // ... some async code using `user`
      });
      return Promise.all(promises);
    });
});

processUsers()
  .then(function() {
    console.log('Finished');
  })
  .catch(function(error) {
    console.error(error.stack);
  });

使用 Mongoose 的eachAsync每个用户都会按顺序处理:

function processUsers() {
  return mongoose.connect('mongodb://localhost')
    .then(function() {
      return User.find().cursor().eachAsync(function(user) {
        return // ... some async code using `user`
      });
    })
});

使用async/await

async function processUsers() {
  await mongoose.connect('mongodb://localhost');
  await User.find().cursor().eachAsync(async function(user) {
    await // ... some async code using `user`
  });
}

我认为在我们的例子中最好使用瀑布,像这样

async.waterfall([
    function (callback) {
        mongoose.connect("mongodb://localhost/****");
        var db = mongoose.connection;
        db.on('error', console.error.bind(console, 'connection error...'));
        db.once('open', function () {
            callback(null);
        });
    },
    function(callback){
        var users = mongoose.model('User', new mongoose.Schema({
            name: String,
            age: Number
        }));
        users.find(function(err, userFound) {
            if (err) {
                return callback(err);
            }
            callback(null, userFound);
        });
    },
    function(usersData, callback){
        async.each(usersData, function(userData, callback) {
        }, callback);
    }
], function (err, result) {
});

关于瀑布与系列的差异有很好的解释

另一种选择:

functionProcess = (callback) => {
  userModel.find().cursor().eachAsync(user => {
    return user.save().exec();        // Need promise
  }).then(callback);     //Final loop
}