Как объединить несколько обещаний во время итерации массива после разрешения исходного обещания? - PullRequest
0 голосов
/ 12 июня 2019

У меня есть функция (buildMetaData), которая выполняет следующие действия:

1. It receives an array(`items`) as a param
2. It invokes an DAO to fetch some data from a downstream service.
3. The downstream service responds with a promise (initial promise).
4. In the "then"(resolving initial promise), I need to modify the array passed in the param and return the modified array.

На шаге 4 я отображаю массив items, изменяя элемент массива, и мне нужно вызвать другую функцию, котораявозвращает массив обещаний.Мне нужно разрешить это обещание, чтобы установить элемент массива.Как мне связать этот массив обещаний с первоначальным обещанием?

buildMetaData(items) {
   return checkoutDAO.get(items[0].id)
      .then((order) => {
          return items.map((item) => {
              let res = {};
              // some processing 

              const promises = this.buildItemMeta({itemType: item.type, itemId: item.id})

              promises.spread((product, media) => {
                res.size = this.getItemSize(product, media);
              });
              return res;
          });
      });
}

buildItemMeta({itemType, itemId}) {
    const promises = [
      productDAO.get(itemType), // this is a promise
    ];
    promises.push(mediaDAO.get(itemId`)); // this is a promise
    return Promise.all(promises);
}

Я хочу, чтобы новый новый массив имел свойство res.size, которое должно быть разрешено, но на самом деле обещание. Все создают новый экземпляр обещания, а не связывают его с первоначальным обещанием.

ps этот проект использует continuation local storage (cls), cls имеет некоторые известные проблемы с async / await, поэтому я не могу использовать async / await для решения этой проблемы.

Пожалуйста, дайте мне знать, если это требует дальнейшего объяснения,Я ценю любые попытки ответить на этот вопрос.

1 Ответ

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

Это выполняет шаги, но в порядке, который имеет смысл асинхронно.Мышление процедурно может быть не лучшим способом решения асинхронной проблемы, когда нельзя использовать async/await.Пожалуйста, дайте мне знать, если у вас есть какие-либо вопросы.

Так вот:

  1. Он получает массив (items) в качестве параметра
  2. Он вызывает DAOполучить некоторые данные из нисходящего сервиса.
  3. нисходящий сервис отвечает обещанием (начальным обещанием).
  4. В «then» (разрешении начального обещания) мне нужно изменить массивпередается в параметре и возвращает измененный массив.

Теперь становится таким:

  1. Получает массив (items) в качестве параметра
  2. Он извлекает метаданные для каждого элемента и сохраняет массив созданных обещаний
  3. . В нем хранится обещание, полученное при обращении к нисходящему сервису.
  4. Все обещания разрешаются
  5. .Затем 'передаются метаданные элемента и порядок, которые используются в качестве заключительного этапа, на котором они объединяются

Обратите внимание, я также упростила некоторые из ваших кодов.

buildMetaData(items) {
  const itemMetaPromises = items.map(item => this.buildItemMeta(item.type, item.id));
  const orderPromise = checkoutDAO.get(items[0].id);
  Promise.all([...itemMetaPromises, orderPromise])
    .then(data => {
       // data[0] = itemMeta([itemType,itemId]), data[1] = order
      //combine order and items here
    });
}

buildItemMeta(itemType, itemId) {
    return Promise.all([productDAO.get(itemType),mediaDAO.get(itemId)]);
}

Вот фиктивная реализация, чтобы показать вывод.

function buildMetaData(items) {
  const itemMetaPromises = items.map(item => buildItemMeta(item.type, item.id));
  const orderPromise = checkoutDAO.get(items[0].id);
  Promise.all([...itemMetaPromises, orderPromise])
    .then(data => {
      console.log(data);
    });
}

function buildItemMeta(itemType, itemId) {
  return Promise.all([productDAO.get(itemType), mediaDAO.get(itemId)]);
}

checkoutDAO = {
  get: () => new Promise((resolve) => {
    resolve('order')
  })
}
productDAO = {
  get: () => new Promise((resolve) => {
    resolve('product')
  })
}
mediaDAO = {
  get: () => new Promise((resolve) => {
    resolve('media')
  })
}

items = [{
  type: 'itemType',
  id: 'itemId'
}, {
  type: 'itemType',
  id: 'itemId'
}, {
  type: 'itemType',
  id: 'itemId'
}, {
  type: 'itemType',
  id: 'itemId'
}];


buildMetaData(items);
...