【问题标题】:Mongoose and promises: how to get an array of query results?Mongoose 和 Promise:如何获取查询结果数组?
【发布时间】:2014-05-12 18:07:06
【问题描述】:

使用 mongoose 从 db 和 Q 查询结果以获取承诺,但发现我很难仅仅获得可用用户列表。目前我有一些类似的东西:

var checkForPerson = function( person ) {
    people = mongoose.model('Person', Person)

    return people.findOne({"_id": person }, function(err, doc) {
        if (err) console.log(err)

        if (doc !== null) {
            return doc
        } else { 
            console.log('no results')
        }

    })
}

var promises = someArrayOfIds.map(checkForPerson);

// this is where I would like to have an array of models
var users = Q.all(promises)

//this fires off before the people.findOne query above to users is undefined
SomeOtherFunction( users )

如何在SomeOtherFunction 之前完成查询而不进行大量草率回调?

【问题讨论】:

    标签: node.js mongodb mongoose promise q


    【解决方案1】:

    另一个建议是使用 MongoDB 的 $in 运算符将数组传递给 find 并有效地获得大量结果。每个都是 Mongoose 对象。

    var promise = people.find({ _id: { $in: someArrayOfIds }).exec();
    promise.then(function(arrayOfPeople) {
      // array of people ... do what you want here...
    });
    

    这比发出多个请求要高效得多,每个_id 一个。

    【讨论】:

    • 从来不知道$in,我一定会试试这个!
    • @delboud op 如果这是最终解决您的问题的答案,您应该考虑接受它而不是您刚刚接受的我。老实说,虽然我的回答提供了更多关于 IMO 承诺的理论背景和有用信息 - 这是在猫鼬中面临这个问题的人们的实际答案。如果你觉得我的答案有用,你可以投票赞成,但我完全赞成实用的解决方案:)
    • 我实际上是在为承诺而苦苦挣扎,所以你回答了我的问题,但是,他让我了解了一个功能。无论哪种方式与我:)
    • 很高兴能帮您解决问题:)
    【解决方案2】:

    “我如何继续承诺”这个问题的答案几乎总是.then。这是; 的promise 类比,它终止了一个异步语句。你可以在其中返回承诺,它会在继续之前解开它们。

    Q.all(promises).then(function(users){
        SomeOtherFunction(users);
    });
    

    或者干脆Q.all(promise).then(SomeOtherFunction)

    您还需要 findOne 来实际返回 Promise。您可以使用调用节点函数的Q.nfcallpromisify it yourself

    Q.all 所做的是接受一系列承诺,并在 所有 承诺时兑现,并在其中一个拒绝时拒绝。您可能希望附加一个.catch 处理程序以防任何查询失败或使用.done 来表示链的结束。即使没有 .done 或添加显式处理程序,其他承诺库(如 Bluebird)也会为您选择错误,遗憾的是 Q 不会这样做。

    【讨论】:

    • 仅供参考:findOne().exec() 返回一个 Promise。
    • @WiredPrairie 在这种情况下 - OP 绝对应该使用 findOne(..).exec 而不是打扰 nfcall 或手动承诺它。 OP - 另请注意,这意味着您不需要所有 .if(err) 的东西,承诺会为您处理。
    【解决方案3】:

    你也可以使用 q (npm install q)

    var q = require('q')
    , aPromise = mongooseModelA.find({_id: aId}).exec()
    , bPromise = mongooseModelB.find({_id: bId}).exec();
    
    q.all([aPromise, bPromise]).then(function(bothA_and_B) {
      console.log(bothA_and_B);
    });
    

    【讨论】:

      【解决方案4】:

      这里可以选择使用 Promise API:

      const arrayFullOfPromises = [];
      arrayFullOfPromises.push(mongooseModelA.find({_id: aId}).exec());
      arrayFullOfPromises.push(mongooseModelB.find({_id: bId}).exec());
      Promise.all(arrayFullOfPromises).then(results => console.log(results));
      

      【讨论】:

        猜你喜欢
        • 2017-11-19
        • 2017-07-22
        • 2021-04-29
        • 2017-01-06
        • 2019-03-11
        • 1970-01-01
        • 2016-02-23
        • 1970-01-01
        • 2016-06-14
        相关资源
        最近更新 更多