1

Необходимо выполнить ряд http запросов на сервер. При этом, данные для последующего запроса, получаются из предыдущего запроса. Задача в разы усложняется тем, что с сервера возвращается массив параметров, каждый из которых необходимо использовать в последующем запросе(проще говоря, перебираются полученные параметры через map, и затем с каждым из параметром отправляется новый запрос, своего рода рекурсия).

Упрощенный пример кода:

const people = [];

 ['32', '47', '96'].map(id => {
     let arrayOfNames = sendRequest(id);
     arrayOfNames.map(name => {

         let arrayOfAges = sendRequest(id, name);
         arrayOfAges.map(age => {
             people.push({id: id, name: name, age: age});
         });

     });
 });

 function sendRequest(id, name='') {
     // Эта функция должна СИНХРОННО вернуть полученные данные
     return fetch(`http://website.com/get_data?id=${id}&name=${name}`)
     .then(data => data.somehowConvertToArray());
 } 

То есть, задача стоит сделать функцию sendRequest синхронной. Пробовал много разных вариантов. И через цепочку promise().then(), и разными способами подставлять async/await. Всё безуспешно.

*

UPD: Кое-какое решение мне все-таки пришло в голову, например такое:

let people = [];
const state = [
    {value:'32'},
    {value:'47'},
    {value:'96'}
];
let promiseArray;

// Запросы первого уровня вложенности
promiseArray = [];
state.map(id => {
    let newPromise = sendRequest(id, id.value);
    promiseArray.push(newPromise);
});
await Promise.all(promiseArray);

// Запросы второго уровня вложенности
promiseArray = [];
state.map(id => {
    id.inner.map(name => {
        let newPromise = sendRequest(id, id.value);
        promiseArray.push(newPromise);
    });
});
await Promise.all(promiseArray);

// Преобразование state в нужный формат
people = normilizeState(state);

function sendRequest(link, id, name='') {
    return new Promise(resolve => {
        fetch(`http://website.com/get_data?id=${id}&name=${name}`)
        .then(data => {
            let parsedDate = data.somehowConvertToArray();
            parsedDate.map(item => {
                link.inner.push({value: item});
            });
            resolve();
        });
    });
}

Кратко поясню. Сперва выполняются все запросы первого уровня, после чего используя await Promise.all() ожидается ответ от них. То есть, на моем примере, отправляются все id и получаются все name. Затем записываем данные в переменную state. После этого выполняются запросы второго и так далее, до бесконечности. В итоге state будет иметь примерно такой вид, поэтому его придется еще дополнительно преобразовать, если есть необходимость:

const state = [
  {
      value: '32',
      inner: [
          {
              value: 'Tom',
              inner: [
                  {value: '19'},
                  {value: '22'},
                  {value: '16'},
                  ...
              ]
          },
          {
              value: 'Bob',
              inner: [...]
          },
          ...
      ]
  },
  ...
];

Если кто-то придумает более элегантное решение данной задачи - пишите.

Daniil
  • 11
  • 2
  • Вопрос закрыли, хотя это совсем не дубликат.. – Daniil Jun 09 '20 at 21:53
  • Почему не дубликат? Вполне себе дубликат. – Grundy Jun 10 '20 at 03:50
  • В тех темах, которые вы предложили, нету ничего подобного. Запросы должны быть СИНХРОННЫЕ, а также заранее не известно общее количество запросов и количество запросов следующего уровня вложенности. Все зависит от ответа, предыдущего запроса. – Daniil Jun 11 '20 at 10:11
  • Запросы не могут быть синхронные, так как они асинхронны. Как дождаться результата асинхронной функции либо нескольких функций описано в вопросах дубликатах. – Grundy Jun 11 '20 at 10:40

0 Answers0