@LazarchukNazar
Джаваскриптизер

Как получить результаты нескольких первых выполненных Promise?

Дано:
Проект на реакт, в коротом есть строка поиска. Во время ввода значения срабатывают AJAX-ы для того, чтобы получить подсказки (suggestions) в количестве 8-10 штук на разные дата-сорсы.

Проблема:
Нужно показать результат двух аяксов, которые быстрее пришли, а все остальные отменить.
Сейчас оно работает на Promise.all, который ждёт выполнение всех промисов, он не подходит.
Я знаю что в есть метод Promise.race, но он ждёт только первый аякс (это уже чуть ближе к тому что мне нужно).

Есть ли в JS решение данной задачи или нужно писать костыль? Если костыль, то пожалуйста напишите пример, дописать реализацию:
const ajax1 = new Promise((res, rej) => setTimeout(() => res({ data1: 'work'}), 3000));
const ajax2 = new Promise((res, rej) => setTimeout(() => res({ data2: 'work'}), 6000));
const ajax3 = new Promise((res, rej) => setTimeout(() => res({ data3: 'work'}), 1000));
const ajax4 = new Promise((res, rej) => setTimeout(() => res({ data4: 'work'}), 5000));

let result = {};

// .... реализация

console.log(result); // { data3: 'work', data1: 'work' }
  • Вопрос задан
  • 107 просмотров
Решения вопроса 2
0xD34F
@0xD34F Куратор тега JavaScript
const getFisrtPromises = (promises, count) =>
  new Promise(resolve => {
    const results = [];

    const onResolve = result =>
      results.length < count &&
      [ count, promises.length ].includes(results.push(result)) &&
      resolve(results);

    promises.forEach(n => n.then(onResolve));
  });
Ответ написан
Комментировать
Kozack
@Kozack Куратор тега JavaScript
Thinking about a11y
Ну, вот вам с ходу костыль:
  1. Создаёте AbortController и передаёте его во все вызовы.
  2. Для каждого вызова добавляете один и тот-же обработчик
  3. В нем, условно пушите полученный результат в какой-то массив. И тут же проверяете количество результатов в этом массиве.
  4. Если их два -- вызвать abort чтобы отменить все остальные вызовы
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы