Дочерние функции и асинхронные ожидают - PullRequest
0 голосов
/ 14 июня 2019

В одной из моих конечных точек API я получаю ресурс json (1) из Интернета и редактирую его в соответствии со своими потребностями. В «самой низкой» или «самой глубокой» части дерева я пытаюсь получить другой ресурс и добавить его в конечный объект json. Я относительно новичок в async / await, но пытаюсь отойти от «старых» Promise s, поскольку вижу преимущество (или выигрыш) в использовании async / await.

Объект из (1) выглядит так:

const json = {
  date,
  time,
  trips: [{
    name,
    legs: [{
        id
      },
      {
        id
      }
    ]
  }]
};

Вот как я «переформатирую» и изменяю объект json;

{
  date,
  time,
  trips: json.trips.map(trip => formatTrip(trip))
};

function formatTrip(trip) {
  return {
    name,
    legs: trip.legs.map(leg => formatLeg(leg))
  };
};

async function formatLeg(leg) {
  const data = await fetch();

  return {
    id,
    data
  };
};

Проблема в том, что после того, как я «переформатировал / отредактировал» исходный json, чтобы посмотреть, как я его хочу (и пробежал по всем format... функциям), объекты legs пустые {}.

Я подумал, что это может быть из-за того, что асинхронные / ожидающие обещания не заканчиваются. Я также читал, что если дочерняя функция использует async / await, все вышестоящие функции должны также использовать async / await.

Почему? Как я могу переписать свой код, чтобы он работал и выглядел хорошо? Спасибо!

EDIT:

Я обновил свой код в соответствии с ответом Рэнди. getLegStops(leg) по-прежнему не определено / пусто.

function formatLeg(leg) {
  return {
    other,
    stops: getLegStops(leg)
  };
};

function getLegStops(leg) {
  Promise.all(getLegStopRequests(leg)).then(([r1, r2]) => {
    /* do stuff here */
    return [ /* with data */ ];
  });
};

function getLegStopRequests(leg) {
  return [ url1, url2 ].map(async url => await axios.request({ url }));
};

1 Ответ

0 голосов
/ 14 июня 2019

Две вещи приводят вас к желанию вложить эти Обещания:

  1. Старый взгляд на обратные вызовы и затем Обещания
  2. Считая, что программный процесс должен соответствовать структуре данных

Похоже, вам нужно иметь дело с Обещаниями только один раз, если я правильно понимаю.

Вот так:

async function getLegs(){
 return trip.legs.map(async leg => await fetch(...)); // produces an array of Promises
}

const legs = Promise.all(getLegs());

function formatLegs(legs) {
   // do something with array of legs
};

function formatTrip(){
   //format final output
}

РЕДАКТИРОВАТЬ: согласно вашему комментарию ниже, этот фрагмент представляет то, что я продемонстрировал и как должна выглядеть ваша цель.Пожалуйста, внимательно изучите ваш код.

const arr = [1, 2, 3, ];

const arrPromises = arr.map(async v => await new Promise((res) => res(v)));
const finalPromise = Promise.all(arrPromises);
console.log(finalPromise.then(console.log));
...