Нужен совет по обещанию в обещании и как его лучше написать - PullRequest
0 голосов
/ 01 ноября 2018

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

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

Надеюсь, я сказал это правильно, ха-ха. И если есть какие-то статьи, которые я пропустил, как решить эту проблему, было бы также здорово!

.then(response => {
  // Make copy of the response
  const bookObject = response

  // Loop through each book
  bookObject.forEach((book, index) => {

    // Find the color pallete
    splashy.fromUrl(book.coverImage)
    .then(dominantColors => {

      // Create new key and add it to the list
      bookObject[index].dominantColors = dominantColors
    })
  })

  // Pass through to 
  return bookObject
})

Ответы [ 3 ]

0 голосов
/ 01 ноября 2018

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

async function myFunction() {
  const response = await functionThatReturnsResponse();
  const bookObject = response
  const morePromises = bookObject.map((book, index) => {
    splashy.fromUrl(book.coverImage)
      .then(dominantColors => {
        bookObject[index].dominantColors = dominantColors;
      });
  });

  await Promise.all(morePromises);

  return bookObject;
}

Ссылки:
async/await: https://javascript.info/async-await
Promise.all(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

0 голосов
/ 01 ноября 2018

Во-первых, вы не делаете копию ответа, вы просто создаете дополнительную ссылку на него. Тебе это не нужно.

Вы используете цикл и выполняете действие для каждого элемента в массиве, но на самом деле вы хотите преобразовать их в Обещания, которые разрешаются с вашими изменениями. Для этого вы должны использовать .map() для чего-то вроде:

// Loop through each book
return Promise.all(response.map(book =>
  // Find the color palette
  splashy.fromUrl(book.coverImage).then(
    dominantColors => {
      // Create new key and add it to the list
      book.dominantColors = dominantColors
      return book;
    })
));

Это превращает ваш ответ в массив Обещаний, где каждое Обещание преобразуется в книгу с добавлением dominantColors. Обтекание этого с Promise.all() изменяет это с массива Обещаний на одно Обещание, которое преобразуется в массив с вашими результатами.

0 голосов
/ 01 ноября 2018

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

const call = (arg) => new Promise((resolve, reject) => resolve(arg));
call(1)
  .then((a) => call(a))
  .then((a) => console.log(a, 'Finished!')) // 1 Finished!

Однако ваш вариант использования немного сложнее, так как вы выполняете несколько асинхронных действий внутри вызова then. Вам нужно сгруппировать их всех в одно Обещание с Promise.all

const call = (arg) => new Promise((resolve, reject) => resolve(arg));
call(6)
  .then(() => {
    const args = [2,3,4];
    const promises = args.map((arg) => call(arg));  // Execute the async function and store the promise into the resulting array.
    return Promise.all(promises);  // Waits for every promise in the array to complete before continuing.
  })
  .then((results) => console.log(results.join(' '), 'Finished!')) // 2 3 4 Finished!
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...