Async - Orgchart, сформированная множественными вызовами API на основе обещаний, возвращающими данные, зависящие друг от друга - PullRequest
0 голосов
/ 22 октября 2018

Я делаю организационную диаграмму, показывающую иерархию единиц в виде сетки.Вызов API возвращает объект JSON, содержащий единицу и массив всех его дочерних элементов.Родитель и дети имеют идентификаторы вместе с некоторыми другими ошибочными данными.Чтобы диаграмма была наиболее производительной, я не загружаю больше «строк», чем в окне браузера.Ограничения проектирования, которым я следую, устанавливают, что дочерний элемент, находящийся непосредственно под родительским элементом, должен быть промежуточным дочерним элементом.После загрузки всех модулей, которые могут уместиться в исходном окне браузера, им необходимо получить соответствующий стиль, который помещает их в CSS-сетку.

Допустим, у нас есть место для пять rows Math.floor(window.innerHeight / 150);

API принимает идентификатор объекта в качестве запроса, если вы передадите 0, вы получите модуль верхнего уровня.Чтобы получить первые две строки (parent & children), мы вызываем fetch('…/api/org/0').

Затем нам нужно найти дочернего центра и сделать новый вызов на основе его идентификатора

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

Теперь у нас есть 3 строки данных.Этот последний шаг нужно сделать еще два раза, чтобы у нас было 5 строк.Опять же, количество строк, которые соответствуют начальному окну браузера, может измениться.В качестве примера я использую 5.

После того, как все данные получены, мне нужно проверить, какие строки имеют наибольшее количество дочерних элементов, чтобы я мог установить количество столбцов для всеобъемлющей CSS-сетки.И тогда я могу начать делать необходимые манипуляции с DOM и CSS-стилизацией для отображения всех данных в сетке.При этом я чувствую, что было бы неплохо, чтобы данные, созданные вышеуказанными вызовами API, были в одном объекте.

Это не было бы проблемой, если бы код был синхронный ,но fetch основан на обещании , поэтому вводится мир async .Я не хочу блокировать основной поток, поэтому я понимаю, что асинхронность идеальна.Я не могу обернуться, делая последовательные вызовы API, где данные из предыдущего вызова необходимы и доступны для следующего вызова.И если возможно получить один объект, содержащий разные «строки», к которым я могу получить доступ при выполнении DOM-манипуляций / стилей после получения необходимых данных.

Любые предложения / входные данные очень приветствуются!

1 Ответ

0 голосов
/ 22 октября 2018

Это тип ситуации, когда обещания значительно упрощают вашу жизнь по сравнению с обратными вызовами.

Общая идея будет такой:

  • Создайте функцию async, которая будет возвращатьодин вызов API (т. е. обещание вашего вызова API)
  • Создание функции async, которая будет возвращать объект, содержащий построенный объект и набор строк ({result: {id: 0, children: [{...}, {...}], rows: [0: [{...}], 1: [{...}, {...}], 2: [{...}, {...}, {...}]})
  • Inэто await запрос API для записи 0 и использование его в качестве «корня» (или начальная строка с предыдущей строкой, если сетка была прокручена и вы загружаете больше)
  • Зацикливание на любом количестве последующих необходимых вам строк

    • Зацикливание на родительских элементах в предыдущей строке и получить дочерние элементы для каждого, прикрепив их к соответствующему родительскому объекту, а также к соответствующему массиву строк (так что вы можете легко получить счет)
      • await вызов вашей функции «получить один элемент»
      • поместить полученный элемент в дочернее свойство его родителя (или подобное), а также вправильный массив строк
  • Возвращает результат, который имеет как дерево объектов, так и массив строк

Примечания:

  • Изучите Promise.all как способ запросить все дочерние элементы в одном ряду одновременно или как-то ограничить его реализацию, чтобы выполнить более 1 запроса ввремя
  • Если у вас есть доступ к изменению API, было бы гораздо эффективнее добавить конечную точку дерева, которая занимает глубину.В зависимости от размера этой диаграммы, может быть более эффективно возвращать одно полное дерево, чем делать десятки запросов.С другой стороны, ваша конечная точка дерева может принимать значения startLevel и endLevel и возвращать только раздел.
...