在插入之前执行数据获取

时间:2019-11-14 12:08:39

标签: javascript express knex.js

我试图先在循环内使用Knex在MySQL中插入数据,然后再获取数据。但是,获取数据首先在插入之前执行。 有人可以帮我吗?

for (let i = 0; i < fileArray.length; i++) {
  fileLocation = fileArray[i].location;
  imgLocationArray.push(fileLocation);
  knex("files")
    .insert({
      fileLink: fileLocation,
      todoId: todoId,
      userId: userId
    })
    .then(() => {
      console.log("phle chala!");
    })
    .catch(err => console.log(err));
}

knex("files")
  .where("files.userId", userId)
  .then(userFiles => {
    console.log("baad wala hai yrr");
    res.json({
      userFiles: userFiles
    });
  })
  .catch(err => console.log(err));

1 个答案:

答案 0 :(得分:1)

使用诺言时(如Knex查询所做的那样),JavaScript将直接继续到下一条语句,而无需等待前一条语句完成。这就是您在这里遇到的:您的代码启动所有数据库插入,但是在发出查询以取回数据之前,不等待它们完成。

由于您要遍历一系列文件,Promise.all是解决方案的理想选择。运作方式如下。首先,我们兑现了所有承诺:

const insertions = fileArray.map(file => {
  fileLocation = fileArray[i].location;
  imgLocationArray.push(fileLocation);
  return knex("files")
    .insert({
      fileLink: fileLocation,
      todoId: todoId,
      userId: userId
    })
})

请注意此处的return语句,这非常重要。接下来,我们等待等待所有这些诺言完成:

  Promise.all(insertions)
    .then(() => knex("files").where("files.userId", userId))
    .then(userFiles => {
      console.log("baad wala hai yrr");
      res.json({
        userFiles: userFiles
      });
    })
    .catch(err => console.log(err));

只有在最后一个.then块中,我们才能依赖于可用数据,因为所有先前的查询都已完成。

如果您恰巧在服务器上有async / await可用的环境中(7.6之后的节点版本),则可以执行以下操作:

try {
  await Promise.all(insertions);
  const userFiles = await knex("files").where("files.userId", userId);
  res.json({ userFiles });
} catch (e) {
  // Handle database error
}

许多人发现此语法更具可读性。请注意,包含此代码的函数必须使用async关键字声明:

myExpressRouter.post("userfiles", async (req, res) => {
  // ...
})