Асинхронный JavaScriptСтатические методы промисовmedium

Полифил Promise.any

Необходимо реализовать полифил стандартного метода Promise.any.

Как работает any

Функция any принимает промисы и возвращает новый промис. Этот промис резолвится успешно в тот момент, когда зарезолвился первый по времени успешный промис, значением этого промиса.

const p1 = Promise.reject("💣") const p2 = Promise.resolve("✅") any([p1, p2]).then(value => { console.log(value); // "✅" });

Если все промисы реджектнулись, итоговый промис реджектится ошибкой AggregateError с сообщением "All promises were rejected" и массивом причин реджекта каждого из промисов.

const p1 = Promise.reject("💣") const p2 = Promise.reject("🌪️") const p3 = Promise.reject("🔥") any([p1, p2, p3]).catch(error => { console.log(error instanceof AggregateError); // true console.log(error.message); // "All promises were rejected" console.log(error.errors); // ["💣", "🌪️", "🔥"] });

Дополнительные требования

Подробное описание того, как работает Promise.any можно прочитать на mdn.

  • any принимает iterable, например, Array или Set.
  • Элементы этого iterable могут быть промисами или не промисами.
  • Если в iterable есть элементы, не являющиеся промисами, то итоговый промис зарезолвится первым из них.
  • Итоговый промис резолвится, когда первым резолвится один из промисов, значением этого резолвнутого промиса.
  • Если передается пустой iterable, итоговый промис реджектится ошибкой AggregateError с пустым массивом errors.
  • Ошибки в массиве errors расположины в том же порядке, в каком промисы находились в iterable.

Код для тестирования

const rand = () => Math.random() * 2000; const p1 = new Promise(r => setTimeout(r, rand(), "A")); const p2 = new Promise(r => setTimeout(r, rand(), "B")); const p3 = new Promise(r => setTimeout(r, rand(), "C")); const p4 = new Promise(r => setTimeout(r, rand(), "D")); any([p1, p2, p3, p4]).then( value => console.log("1 >>>", value), reason => console.log("2 >>>", reason), );