同步迭代在 JavaScript 中不起作用

Synchronous iteration not working in JavaScript

我正在尝试遍历数组并为每个被迭代对象创建记录。这就是我在另一个问题中提到的所做的事情:

async.each(data, (datum, callback) => {
  console.log('Iterated')

  Datum.create({
    row: datum,
  }).exec((error) => {
    if (error) return res.serverError(error)
    console.log('Created')
    callback()
  })
})

不幸的是,结果是:

Iterated
Iterated
Iterated
Created
Created
Created

这不是我们想要的:

Iterated
Created
Iterated
Created
Iterated
Created

我做错了什么?

看起来Datum.create是一个异步函数。 forEach 遍历数组的三个元素中的每一个,依次记录它们。由于 JavaScript 不会在返回异步事件之前阻塞,因此您可以依次获得每个 console.logs。 然后在 一些 时间后,结果出现并且 "created" 被记录到控制台。

您似乎在使用异步数据处理库。对于你想要得到的结果,你需要对数据进行同步处理。方法如下:

data.forEach(function(datum) {
  console.log('Iterated')

  Datum.create({
    row: datum,
  }).exec((error) => {
    if (error) return res.serverError(error)
    console.log('Created')
    callback()
  })
})

您现在可能还想完全删除 callback 函数,因为数据是同步处理的。

async.eachSeries() 一次会 运行 一次迭代,并等待每次迭代终止,然后再进行下一步。

I create an unique user friendly identifier before each creation (like 1, 2, 3 and so on). For that, I've to query the data base to find the latest identifier and increment it which is not available because the records are nearly created at the same time.

这听起来像是瓶颈。我不喜欢 运行 串联异步代码,因为这通常会减慢进程。这种方法怎么样:

  • 由于 data 你知道你需要多少标识符。
  • 在后端实现一个函数,一次不创建单个但 n 这样的标识符 (包括必要的递增等) 和 return 那个数组到前端。现在您可以 运行 将您的常规请求并行 using/mapping 到数据数组的预先计算的 ID 数组。

这应该将 运行 时间从 (createAnId + request) * data.length 减少到单次迭代的 运行 时间。由于所有这些请求都可以 运行 并行,因此大部分都是重叠的。