Promise.allSettled в реализации Babel ES6
Я использую babel
для перевода моего кода [email protected]
, и я застрял с promises.
Мне нужна функция allSettled
-type, которую я мог бы использовать в q
и bluebird
или angular.$q
, например.
В ядре babel-js Promise
метода allSettled
нет.
В настоящее время я использую q.allSettled
в качестве обходного пути:
import { allSettled } from 'q';
Есть ли что-то подобное в babel polyfill? В качестве альтернативы, который является хорошим алгоритмом для меня, чтобы попытаться реализовать?
Ответы
Ответ 1
В качестве альтернативы, который является хорошим алгоритмом для меня, чтобы попытаться реализовать?
- создайте новое обещание с функцией
- использовать массив счетчиков/результатов в объеме исполнителя
- зарегистрировать обратный вызов then() с каждым родительским обещанием, сохраняя результаты в массиве
- разрешить/отклонить обещание с шага 1, когда счетчик указывает, что выполнены все родительские promises
Ответ 2
2019 Ответ
Было предложение добавить эту функцию в стандарт ECMAScript, и оно было принято! Ознакомьтесь с документами Promise.allSettled
.
Оригинальный ответ
Если вы посмотрите на реализацию q.allSettled, вы увидите, что на самом деле это довольно просто реализовать. Вот как вы можете реализовать это с помощью ES6 Promises:
function allSettled(promises) {
let wrappedPromises = promises.map(p => Promise.resolve(p)
.then(
val => ({ status: 'fulfilled', value: val }),
err => ({ status: 'rejected', reason: err })));
return Promise.all(wrappedPromises);
}
Ответ 3
Здесь моя попытка на что-то подобное, у меня есть служба рассылки новостей, и в моем случае я хотел, чтобы мое обещание allSettled разрешалось с помощью массива всех результатов (отклонения и разрешения), В ЗАКАЗ, после того, как все адреса электронной почты будут урегулированы (все электронные письма исчезли):
Newsletter.prototype.allSettled = function(email_promises) {
var allSettledPromise = new Promise(function(resolve, reject) {
// Keep Count
var counter = email_promises.length;
// Keep Individual Results in Order
var settlements = [];
settlements[counter - 1] = undefined;
function checkResolve() {
counter--;
if (counter == 0) {
resolve(settlements);
}
}
function recordResolution(index, data) {
settlements[index] = {
success: true,
data: data
};
checkResolve();
}
function recordRejection(index, error) {
settlements[index] = {
success: false,
error: error
};
checkResolve();
}
// Attach to all promises in array
email_promises.forEach(function(email_promise, index) {
email_promise.then(recordResolution.bind(null, index))
.catch(recordRejection.bind(null, index));
});
});
return allSettledPromise;
}
Ответ 4
Вот еще один вариант с той же функциональностью: spex.batch
Исходный код был бы слишком большой для повторной публикации здесь, так что вот пример из пакетная обработка о том, как его использовать:
var spex = require('spex')(Promise);
// function that returns a promise;
function getWord() {
return Promise.resolve("World");
}
// function that returns a value;
function getExcl() {
return '!';
}
// function that returns another function;
function nested() {
return getExcl;
}
var values = [
123,
"Hello",
getWord,
Promise.resolve(nested)
];
spex.batch(values)
.then(function (data) {
console.log("DATA:", data);
}, function (reason) {
console.log("REASON:", reason);
});
Выводится:
DATA: [ 123, 'Hello', 'World', '!' ]
Теперь давайте сделаем ошибку, изменив getWord
на это:
function getWord() {
return Promise.reject("World");
}
Теперь вывод:
REASON: [ { success: true, result: 123 },
{ success: true, result: 'Hello' },
{ success: false, result: 'World' },
{ success: true, result: '!' } ]
то есть. весь массив решен, сообщая результаты, связанные с индексами.
И если вместо того, чтобы сообщать всю причину, мы вызываем getErrors()
:
console.log("REASON:", reason.getErrors());
тогда выход будет:
REASON: [ 'World' ]
Это просто, чтобы упростить быстрый доступ к списку произошедших ошибок.