猫鼬如何填充非 ID 字段或如何手动实现并行承诺填充

mongoose how to populate non-id field or how to implement parallel promise population manually

我想用 mongoose 填充一个非 id 字段,并且已经在这里找到这些问题:

link1

link2

原来mongoose现在不支持这个功能了。未解决的问题在这里:https://github.com/Automattic/mongoose/issues/2562

所以现在,我想用额外的查询手动填充。但是我在做的时候遇到了一些问题

我有两个模式(回复、用户):

这是回复架构,author_id 引用用户集合的用户名字段而不是 _id;

var ReplySchema = new Schema({
  'content' : {
    type: String,
    required: true

  },
  'author_id' : {
    type:  String,
    ref: 'users'
  },
});

当我收到全部回复时。喜欢:

replies [ {
    content: 'comments one',
    author_id: 'raynlon',
    },
  { 
    content: 'comments two',
    author_id: 'raynlon',
  } ]

从这里开始,我正在进一步从用户 table 查询作者,我所做的是:

 var replies = yield query.exec(); // which already got all the replies  
    var final = [];  

   for (var i = 0; i < replies.length; i++) {
    co(function*(){
      var data = yield User.Model.findOne({username: replies[i].author_id}).select('username email avatar gravatar_id name').exec();
      return data;
    }).then(function(value) {
      final.push(value);
    });
  }

    return final // I need to return the modified data back to the client

我总是空着[];

这是因为 for 循环中的异步代码?

我还找到了一些解决方案,例如: Promise.all(), q.all() 这些有点类似的承诺......

但是我不知道怎么办..

我使用的 co 库说 co() 应该作为承诺返回,理论上,我们可以然后注入 Promise.all([]),但它不起作用......所以任何人都可以帮我解决这个问题?

好的,问题是:您创建了变量 final 并在之后创建了变量 returns,这发生在 Mongo-Query 执行之前。

解决方法:把Promises推送到final,然后在回复客户端的时候一起解决。

function queryAsync() {
  var replies = yield query.exec(); // which already got all the replies  
  var final = [];

  for (var i = 0; i < replies.length; i++) {
    final.push(
      User.Model.findOne({
        username: replies[i].author_id
      }).select('username email avatar gravatar_id name').exec()
    )
  }

  return final; // and array with promises is returned
}

// later in your handler ..
function handler(request, response) {
  // ..

  // query here, and resolve promises in final here
  bluebird.all(queryAsync()).then(function(final) {
    // all promises resolved
    response.send(final);
  })

  // ..
}