推入 forEach 查询无法正常工作 [英] Push inside forEach with query not working properly

查看:51
本文介绍了推入 forEach 查询无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 mongodb 针迹/领域,我正在尝试使用 foreach 修改数组内的对象,并将 id 推送到新数组中.

I'm working with mongodb stitch/realm and I'm trying to modify objects inside an array with a foreach and also pushing ids into a new array.

对于我正在修改的每个对象,我也会先进行查询,在找到文档后,我开始修改对象,然后将 id 推送到另一个数组中,以便稍后可以使用这两个数组.

For each object that i'm modifying, I'm also doing a query first, after the document is found I start modifying the object and then pushing the id into another array so I can use both arrays later.

代码是这样的:

exports = function(orgLoc_id, data){
    var HttpStatus = require('http-status-codes');  
    // Access DB
    const db_name = context.values.get("database").name;
    const db = context.services.get("mongodb-atlas").db(db_name);
    const orgLocPickupPointCollection = db.collection("organizations.pickup_points");
    const orgLocStreamsCollection = db.collection("organizations.streams");
    const streamsCollection = db.collection("streams");
      
    let stream_ids = [];    
  
    data.forEach(function(stream) {
  
      return streamsCollection.findOne({_id: stream.stream_id}, {type: 1, sizes: 1}).then(res => { //if I comment this query it will push without any problem
        if(res) {
          let newId = new BSON.ObjectId();
          stream._id = newId;
          stream.location_id = orgLoc_id;
          stream.stream_type = res.type;
          stream.unit_price = res.sizes[0].unit_price_dropoff;
          stream._created = new Date();
          stream._modified = new Date();
          stream._active = true; 
    
          stream_ids.push(newId);
                              
        }
      })
    })    
    console.log('stream ids: ' + stream_ids);

    //TODO

  };

但是当我尝试记录stream_ids"时,它是空的,什么也没有显示.未分配属性 stream_type 和 unit_price.

But when I try to log 'stream_ids' it's empty and nothing is shown. Properties stream_type and unit_price are not assigned.

我尝试过承诺,但没有成功

I've tried promises but I haven't had success

推荐答案

这是一个异步问题.您正在回调中填充数组的值.但是由于事件循环的性质,在执行 console.log 时不可能调用任何回调.

It's an asynchronous issue. You're populating the value of the array inside a callback. But because of the nature of the event loop, it's impossible that any of the callbacks will have been called by the time the console.log is executed.

您提到了一个涉及 Promise 的解决方案,这可能是正确的方法.例如类似以下内容:

You mentioned a solution involving promises, and that's probably the right tack. For example something like the following:

exports = function(orgLoc_id, data) {
  // ...
  let stream_ids = [];
  const promises = data.map(function(stream) {
    return streamsCollection.findOne({ _id: stream.stream_id }, { type: 1, sizes: 1 })
      .then(res => { //if I comment this query it will push without any problem
        if (res) {
          let newId = new BSON.ObjectId();
          // ...
          stream_ids.push(newId);
        }
      })
  })

  Promise.all(promises).then(function() {
    console.log('stream ids: ' + stream_ids);

    //TODO
    // any code that needs access to stream_ids should be in here...
  });
};

注意 forEachmap 的变化……这样你就得到了所有 Promise 的数组(我假设你的 findOne 由于 .then 返回了一个承诺).

Note the change of forEach to map...that way you're getting an array of all the Promises (I'm assuming your findOne is returning a promise because of the .then).

然后你使用一个 Promise.all 来等待所有的 Promise 被解析,然后你应该有你的数组.

Then you use a Promise.all to wait for all the promises to resolve, and then you should have your array.

旁注:更优雅的解决方案是在您的 .then 中返回 newId.在这种情况下,Promise.all 实际上将使用所有承诺的结果数组进行解析,这将是 newId 的值.

Side note: A more elegant solution would involve returning newId inside your .then. In that case Promise.all will actually resolve with an array of the results of all the promises, which would be the values of newId.

这篇关于推入 forEach 查询无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆