使mongoose.js查询同步运行

Ale*_*lla 20 mongoose mongodb node.js

我有两个猫鼬收藏品.第一个存储地点列表,第二个是访问地点.我的节点代码经过并试图获取每个地方的访问列表并构建一个我输出为JSON的字符串.第一个查询在第二个查询开始之前完成 - 有没有办法使它们同步运行?

Har*_*ngh 17

如果您使用的是node.js,那么您应该使用https://github.com/caolan/async

当您必须从多个集合中获取数据时,您必须多次链接您的查询.

它会使您的代码复杂且难以阅读且无模块化.使用async可以使用mongodb和node.js创建模块化

我项目的示例代码:

var async = require('async');

var createGlobalGroup = function(socket, data) {
    async.waterfall(
    [
    /**
     * this function is required to pass data recieved from client
     * @param  {Function} callback To pass data recieved from client
     */

    function(callback) {
        callback(null, socket, data);
    },
    /**
     * Step 1: Verify User
     */
    verifyUser,
    /**
     * Step 2: Check User Access Rights And Roles
     */
    checkUserAccessRightsAndRoles,
    /**
     * Step 3: Create Project
     */
    createNewGlobalGroup], function(err, result) {
        /**
         * function to be called when all functions in async array has been called
         */
        console.log('project created ....')
    });
}
verifyUser = function(socket, data, callback) {
//do your query
    /**
     * call next function in series
     * provide sufficient input to next function
     */
    callback(null, socket, data, {
        "isValidUser": true,
    });
}

checkUserAccessRightsAndRoles = function(socket, data, asyncObj, callback) {
    //do your query
    if(condition) {
        callback(null, socket, data, {
            roles: result,
            "isValidUser": asyncObj.isValidUser,
            "userId": asyncObj.userId,
        });
    } else {
    //no call back
    }
}

var createNewGlobalGroup = function(socket, data, asyncObj, callback) {
//wanna stop then no callback
}
Run Code Online (Sandbox Code Playgroud)


mr.*_*eze 11

mongodb/mongoose查询没有原生的同步api(你实际上也不想要一个).正如WiredPrarie所提到的,你应该链接查询,第二个查询在第一个完成并运行回调之后开始.这是一个例子:

function findVisits(placesQuery,callback){
    Places.find(placesQuery).exec(function(err,places){
        if (err || !places.length){
            console.log('there was a problem');
            callback(err, null);
        }else{
            var visitQuery = ... //however you want to filter places
            Visits.find(visitQuery).exec(function(err2,visits){
                if (err2 || !visits.length){
                    console.log('there was a problem');
                    callback(err2,null);
                }else{
                    callback(null, visits)
                }
            });
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

  • 修复你的答案:在Node中无法进行同步网络连接. (6认同)
  • 我不同意"(并且你不想要一个实际的)"评论.这是每个开发人员都有自己的需求.例如.在Node REPL控制台中进行调试,逐行分配结果会容易得多.我可能会去一个小插件来做那件事. (3认同)

vse*_*nko 9

如果您使用的是Node 8.x,则可以使用async/await:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await

await运算符暂停执行异步函数,直到Promise被解析并返回该值.这样您的代码看起来会更加同步:

const query1 = MyModel.find({ name: /john/i }, null, { skip: 10 });
const result1 = await query1.exec();

const query2 = MyModel.find({ name: /john/i }, null, { skip: 100 });
const result2 = await query2.exec();
Run Code Online (Sandbox Code Playgroud)

查询将连续执行.

  • 但是它仅在异步函数中使用! (2认同)

joe*_*dle 5

这些天mongoose支持承诺,所以你可以.then()查询.例如:

app.get('/notifications', function (req, res, next) {
  Users.findOne({
    username: req.body.username,
    password: req.body.password,
  }).then(user => {
    if (!user) {
      res.json({success: false, message: "Username or password incorrect."});
      return;
    }

    return Notifications.find({
      user: user._id
    }).then(notifications => {
      res.json({success: true, notifications});
    });
  ).catch(error => {
    //console.error(error);
    //res.json({success: false, error: error.message});
    next(error);
  });
});
Run Code Online (Sandbox Code Playgroud)

或者,现在Javascript具有async-await,您可以使用它,这将节省几行,并稍微展平代码:

app.get('/notifications', async (req, res, next) => {
  try {
    const user = await Users.findOne({
      username: req.body.username,
      password: req.body.password,
    });
    if (!user) {
      res.json({success: false, message: "Username or password incorrect."});
      return;
    }

    const notifications = await Notifications.find({
      user: user._id
    });
    res.json({success: true, notifications});
  } catch (error) {
    //console.error(error);
    //res.json({success: false, error: error.message});
    next(error);
  }
});
Run Code Online (Sandbox Code Playgroud)