【问题标题】:Referencing an array fails because of Asynchronous calls由于异步调用,引用数组失败
【发布时间】:2018-01-05 22:02:05
【问题描述】:

我正在尝试引用 MongoDB 中的文档。我试图在实际调用数据库之前先创建要插入的文档。我用过

const venues = [
  new Venue({ name: 'A' }),
];

const events = [
  new Event({
    name: 'B',
    venue: venues[0]._id
  })
];

但似乎venues[0]._idnull

如果我使用console.log(venues),我确实得到了我想要的数组,所以它不应该说null

我担心这是由于异步调用而发生的,即 const venues = ... 行在启动 const events = ... 代码行之前没有完成。

我可以做些什么来确保const venues = ... 在下一行引用数组之前完成?

编辑

实际上,如果我使用console.log(events),我发现它可以正常工作。

但是当我使用时

Promise.all([Venue.create(venues), Event.create(events)]).then(() => { .. });

会场变成null

【问题讨论】:

  • 我认为您的意思是“异步调用”,因为“同步”意味着它立即返回,而另一个则没有。为什么这些调用是“异步的”?这些看起来就像标准的类构造函数。也许是猫鼬?如果那是来自模型实例的创建,那么它不是“异步”的。如果它实际上是猫鼬,那么null 很可能是因为定义的实际模式与您尝试提供的数据不同。 ObjectId 在实际架构上的可能“参考”。请解释/详细说明。
  • 嗯,Edit 与“新建”实例构造函数完全不同。显示实际代码和您打算做什么。当您调用.create() 时,它是异步的

标签: javascript node.js asynchronous mongoose


【解决方案1】:

您的代码缺少您实际将Venue 对象保存到数据库的部分(这意味着对 MongoDB 的insert 函数的某些调用)。除非您保存它,或手动提供 _id 属性,否则该属性将保持未定义。这与同步\异步代码无关。

编辑:

当您将venues[0]._id 分配给新事件对象的venue 属性时,它是未定义的,因为您还没有调用create 函数。你应该做的是:

  1. 在数据库中创建 Venue 对象
  2. 完成后,分配新创建的_id

可以通过多种方式等待完成:

  1. 使用回调
  2. 使用 Promise 的 .then(...) 函数
  3. await承诺

这完全取决于您的口味和您使用的工具。

最重要的是,请注意Promise.all 将一次执行数组中的所有承诺,因此在这种情况下您不能使用它。

【讨论】:

  • 但是如果我使用new Venue({ ... }),它会自动分配一个ID。但是保存后ID会变吗?
  • 我不知道框架\驱动程序在您调用 new 时会分配 _id。如果您使用的是 MongoDB 的原生 node.js 驱动程序或 Mongoose,则 _id 仅在将文档插入数据库时​​创建。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-12
相关资源
最近更新 更多