I am looking for something similar to Promise.all
that will continue to resolve promises concurrently even in the event that one or more of the promises reject or throw an error. Each request does not rely on another request.
Close to what I want - please see comments
function fetchRequest (request) {
return new Promise(function (resolve, reject) {
fetch(request)
.then(function(response) {
return response.text();
}).then(function (responseXML) {
//Do something here. Maybe add data to dom
resolve(responseXML);
}).catch(function (err) {
reject(new Error(err));
}
}
function promiseRequests (requests) {
var result = Promise.resolve();
for (var i = 0; i < requests.length; i++) {
result = fetchRequest(requests[i])
}
//This is wrong as it will resolve when the last promise in the requests array resolves
// - not when all requests resolve
resolve(result);
}
promiseRequests(['url1.com', 'url2.com']).then(function (data) {
console.log('All requests finished');
//optionally have data be an array of resolved and rejected promises
});
I have succeeding in using Promise.all
together with only ever resolving the fetchRequest promise and this results in the expected outcome (an array of results and undefined
's) but I feel like this is the wrong way to do things. It also removes my ability to use thrown errors.
Works but feels like incorrect use of resolve
function fetchRequest (request) {
return new Promise(function (resolve, reject) {
fetch(request)
.then(function(response) {
return response.text();
}).then(function (responseXML) {
resolve(responseXML);
}).catch(function (err) {
resolve();
}
}
Promise.all([fetchRequest('url1.com'), fetchRequest('url2.com')]).then(function (data) {
console.log('All requests finished', data); //data could be ['resultXML', undefined]
});
Please only native es6 promise API answers thanks.
I have succeeded in using
Promise.all
together with only ever resolving thefetchRequest
promises
That's basically the way to go. ES6 does not have a helper function like allSettled
(Q) or settle
(Bluebird 2.x) for this case, so we will need to use Promise.all
similar to like you did. Bluebird even has a dedicated .reflect()
utility for this.
You would however not resolve them with undefined
in the case of a rejection, but rather with some useful value that allows to identify the errors.
function promiseRequests(requests) {
return Promise.all(requests.map(request => {
return fetch(request).then(res => {
return {value:res};
}, err => {
return {reason:err};
});
}));
}
You are essentially asking for a way to swallow any errors. As such, a function like this will be your best bet:
function swallow(p) {
// transforms rejected promises into promises fulfilled with undefined
return p.catch(function () { });
}
You would use it as follows:
Promise.all([swallow(fetch('url1.com')), swallow(fetch('url2.com'))]).then(function (data) {
console.log('All requests finished', data); //data could be ['resultXML', undefined]
});
or even
const promises = ['url1.com', 'url2.com'].map(fetch).map(swallow);
Promise.all(promises).then(function (data) {
// ...
});
来源:https://stackoverflow.com/questions/30930298/resolve-a-promise-once-all-internal-concurrent-promises-have-resolved-or-rejecte