javascript - 在异步函数内调用异步函数时发生事务完成错误

标签 javascript node.js asynchronous async-await knex.js

我有以下异步函数来复制名为“调查问卷”的 postgres 数据库表中的记录:

const duplicateQuestionnaire = async(trx, originalQuestionnaireId) => {
  const originalQuestionnaire = await trx
    .select("*")
    .from("Questionnaires")
    .where({
      id: originalQuestionnaireId
    })
    .then(head);

  const newQuestionnaireId = await trx
    .table("Questionnaires")
    .insert(omit(originalQuestionnaire, "id"))
    .returning("id")
    .then(head);

  const sectionIDs = await trx
    .select("id")
    .from("Sections")
    .where({
      QuestionnaireId: originalQuestionnaireId
    });

  sectionIDs.map(element => {
    duplicateSection(trx, element.id, newQuestionnaireId);
  });

  return trx
    .select("*")
    .from("Questionnaires")
    .where({
      id: newQuestionnaireId
    })
    .then(head);
};

复制后,它将调用第二个异步函数来复制名为“Sections”的表中的记录:

const duplicateSection = async (trx, sectionId, newQuestionnaireId) => {
  const originalSection = await trx
    .select("*")
    .from("Sections")
    .where({ id: sectionId })
    .then(head);

  const newSection = omit(originalSection, "id");

  newQuestionnaireId ? (newSection.QuestionnaireId = newQuestionnaireId) : null;

  const newSectionId = await trx
    .table("Sections")
    .insert(newSection)
    .returning("id")
    .then(head);

  return trx
    .select("*")
    .from("Sections")
    .where({ id: newSectionId })
    .then(head);
};

These functions are designed with a hierarchy in mind: duplicateQuestionnaire calls duplicateSection as a questionnaire contains sections. The latter function can be called without calling the former initially and does not call it as part of its actions.

The return value of each function is used as a GraphQL return.

这些函数都对数据库产生了预期的效果;他们工作。但是,duplicateQuestionnaire 正在标记此错误:

(node:172) UnhandledPromiseRejectionWarning: Error: Transaction query already complete, run with DEBUG=knex:tx for more info
web_1  |     at completedError (/app/node_modules/knex/lib/transaction.js:303:9)
web_1  |     at /app/node_modules/knex/lib/transaction.js:277:22
web_1  | From previous event:
web_1  |     at Client_PG.trxClient.query (/app/node_modules/knex/lib/transaction.js:275:34)
web_1  |     at Runner.<anonymous> (/app/node_modules/knex/lib/runner.js:155:36)
web_1  | From previous event:
web_1  |     at /app/node_modules/knex/lib/runner.js:61:21
web_1  |     at runCallback (timers.js:810:20)
web_1  |     at tryOnImmediate (timers.js:768:5)
web_1  |     at processImmediate [as _immediateCallback] (timers.js:745:5)
web_1  | From previous event:
web_1  |     at Runner.run (/app/node_modules/knex/lib/runner.js:47:31)
web_1  |     at Builder.Target.then (/app/node_modules/knex/lib/interface.js:39:43)
web_1  |     at duplicateSection (/app/repositories/DuplicateRepository.js:49:6)
web_1  |     at <anonymous>
web_1  | (node:172) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
web_1  | (node:172) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

我知道问题在于我如何处理 .map() 中的每个 duplicateSection 调用,但是经过一些研究和大量的谷歌搜索,我仍然正在努力解决这个问题。

最佳答案

您想要等待由duplicateSections返回的所有 promise :

 await Promise.all(sectionIDs.map(element =>
    duplicateSection(trx, element.id, newQuestionnaireId)
 ));

这不仅可以确保在运行最终查询之前复制所有部分,还可以链接被拒绝的 promise 。

关于javascript - 在异步函数内调用异步函数时发生事务完成错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51931372/

相关文章:

javascript - 向数据表中的项目添加 "data"选项

javascript - Vue.js 在组件/应用程序之外观察 DOM 元素属性

javascript - 如何覆盖参数的默认值?

PowerShell 作业进度监控

asynchronous - 发生某些情况时如何停止 Kotlin 流程

javascript - 当我的 Javascript 函数运行时,我的 A-Frame 没有渲染。我怎样才能让它同时渲染?

c# - javascript 和 C# 中的 SHA1 base64 算法

javascript - 在 Three.js 中使用 OBJLoader 时出现 CORS 问题

html - 在 nodejs 服务器上保存 wav

node.js - 关于非阻塞且快速的服务器、框架、语言的建议?