首页 > 解决方案 > 异步 - 由多个基于 Promise 的 API 调用形成的组织结构图,返回相互依赖的数据

问题描述

我正在制作一个组织结构图,以网格状外观显示单位的层次结构。对 API 的调用会返回一个 JSON 对象,其中包含一个单元及其所有子项的数组。父母和孩子都有 ID 以及其他一些杂项数据。为了使图表具有最高性能,我不会加载比浏览器窗口中更多的“行”。我遵循的设计约束规定,直接低于父级的孩子应该是中间孩子。在加载了所有适合初始浏览器窗口的单元之后,它们需要接收适当的样式,将它们放置在 CSS 网格中。

假设我们有五行的空间Math.floor(window.innerHeight / 150);

API 将 unit-ID 作为查询,如果您传递 0,您将获得顶级单元。要检索前两行(父和子),我们调用fetch('…/api/org/0').

然后我们需要找到 center child 并根据它的 ID 做一个新的调用

let centre = Math.floor(responseFromPreviousCall.children.length / 2);
fetch(`…/api/org/${responseFromPreviousCall.children[centre].id}`);

我们现在有 3 行数据。最后一步需要再做两次,所以我们有 5 行。同样,适合初始浏览器窗口的行数可能会改变。我以 5 为例。

收到所有数据后,我需要检查哪些行的子项数量最多,以便我可以设置总体 CSS 网格的列数。然后我可以开始进行必要的 DOM 操作和 CSS 样式设置以显示网格中的所有数据。这样做时,我觉得将上述 API 调用生成的数据放在一个对象中会很好。

如果代码是同步的,这不会是一个问题,但是 fetch 是基于 promise 的,因此引入了async的世界。我不想阻塞主线程,所以我知道异步是理想的。我无法绕开顺序 API 调用,在这些调用中,前一次调用中的数据对于下一次调用是必要的并且可以访问。如果有可能最终得到一个包含不同“行”的对象,我可以在检索必要的数据后进行 DOM 操作/样式设置时访问它。

非常感谢任何建议/意见!

标签: javascriptasynchronouspromisefetch-api

解决方案


在这种情况下,与回调相比,promise 让你的生活更轻松。

一般的想法是:

  • 创建一个async将返回单个 API 调用的函数(即承诺您的 API 调用)
  • 创建一个async函数,该函数将返回一个包含已构建对象和一组行的对象 ( {result: {id: 0, children: [{...}, {...}], rows: [0: [{...}], 1: [{...}, {...}], 2: [{...}, {...}, {...}]})
  • 在其中,await一个 API 请求记录0并将其用作您的“根”(如果网格已滚动并且您正在加载更多,则使用过去的行播种第一行)
  • 循环遍历您需要的许多后续行

    • 循环上一行中的父对象并获取每个子对象,将它们附加到相应的父对象以及相应的行数组(这样您就可以轻松获取计数)
      • await调用您的“获取一件物品”功能
      • 将获得的项目放在其父级的子属性(或类似属性)中,以及正确的行数组中
  • 返回包含对象树和行数组的结果

笔记:

  • 研究Promise.all作为同时请求一行中的所有孩子的一种手段,或者它的一些节流实现,一次执行多个请求
  • 如果您有权修改 API,则添加需要深度的树端点会更有效。根据此图表的大小,返回单个完整树可能比执行数十个请求更有效。或者,您的树端点可以采用 startLevel 和 endLevel 并仅返回一个部分。

推荐阅读