【问题标题】:Sync + Async POSTing nested parent-children objects to preserve the order同步 + 异步 POST 嵌套的父子对象以保留顺序
【发布时间】:2021-12-04 13:03:46
【问题描述】:

我有一个 Person 对象的嵌套数组。

每个Person 对象都有一个强制name。每个Person 还可以选择有一个children 字段,其中包含一组其他Person 对象(也有一个children 字段-因此家谱的“深度”基本上可以永远持续下去。)

如果没有孩子,children 字段将只是一个空数组 []。

例如

  const family_name = "The Numbers";
  const family = [{
      name: "1",
      children: [],
    },
    {
      name: "2",
      children: [{
          name: "2-1",
          children: [{
            name: "2-1-1",
            children: [],
          }, ],
        },
        {
          name: "2-2",
          children: [],
        }
      ],
    },
    {
      name: "3",
      children: [{
        name: "3-1",
        children: [],
      }, ],
    },
  ]

我需要在“孩子”之前发布“父母”。当我发布Person 时,我会在response.data 中得到它的id。此id 需要在直接子项的 POST 中用作parent_id,以便子项与父项关联。

最上面的Person 需要让他们的parent_id 成为family_name

每个“级别”都需要异步发布,因为我的后端需要保留顺序。(注意:在客户端计算 Person 的顺序并传递该值到后端不是解决方案,因为Person 实际上是一个 MPTT 模型,其中插入顺序很重要。)

例如1 然后2 然后3

例如2 然后2-1 然后2-2

但是,嵌套的Persons 可以同步发布。例如,一旦发布 2 返回 201 响应,它的“兄弟”3 和它的“子” 2-1可以同时发布。

如何以最佳方式将所有Persons 发布到嵌套数组中以保留顺序?请注意,我使用的是 axios。

编辑:这是一些伪代码:

function postPersons(persons, parent_id) {
    // Async POST all objects in persons
    // e.g. POST 1 then 2 then 3 to family_name

    // For each successful POST, if person has children, 
    // async POST those children to that person
    // e.g. Once POST to 2 resolves, POST 2-1 then 2-2 to 2
    // e.g. Once POST to 3 resolves, POST 3-1 to 3

    // Repeat for all successful POSTs
    // e.g. Once POST to 2-1 resolves, POST 2-1-1 to 2-1

}

postPersons(family, family_name)

【问题讨论】:

  • 你写过代码吗?我们无法帮助调试我们看不到的代码。
  • @Andy 不幸的是,我什至不知道从哪里开始。如果有帮助,我已经发布了一些伪代码。

标签: javascript performance asynchronous async-await axios


【解决方案1】:

我建议不要使用async/await 进行顺序循环,而是使用同步循环并分别累积两件事:

  • 按顺序处理的子级承诺(请参阅herethere
  • 所有递归调用的一系列承诺,最终将是Promise.all'd

这确保了正确的顺序以及错误的立即传播。

所以代码看起来像

function postPersons(persons, parent_id) {
    const results = [];
    let chain = Promise.resolve();
    for (const person of persons) {
        chain = chain.then(() =>
            postSinglePerson(person, parent_id)
        );
        results.push(chain.then(result =>
            postPersons(person.children, result.id)
        ));
    }
    return Promise.all(results);
}
postPersons(family, family_name).then(() => console.log('Done'), console.error);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-29
    • 1970-01-01
    • 2021-08-11
    • 1970-01-01
    • 2021-06-09
    • 1970-01-01
    • 2016-08-18
    • 1970-01-01
    相关资源
    最近更新 更多