Skip to content

Instantly share code, notes, and snippets.

@mircoc
Last active December 13, 2017 14:17
Show Gist options
  • Select an option

  • Save mircoc/13caae1dc7a41d87d3e26fe614664cde to your computer and use it in GitHub Desktop.

Select an option

Save mircoc/13caae1dc7a41d87d3e26fe614664cde to your computer and use it in GitHub Desktop.
getFirstPromiseThatCompleteSuccessfullyWithinTimeoutES6: Race two or more promises returning the one that finish first and waiting a maximum amount of time. Raw
const firstThatCompleteSuccessfullyES6 = (options) => {
// return the first promise that resolve
const oneSuccess = (promises) => Promise.all(promises.map(p => {
// If a request fails, count that as a resolution so it will keep
// waiting for other possible successes. If a request succeeds,
// treat it as a rejection so Promise.all immediately bails out.
return p.then(
(val) => { return Promise.reject(val); },
(err) => { return Promise.resolve(err); }
);
})
).then(
// If '.all' resolved, we've just got an array of errors.
(errors) => { return Promise.reject(errors); },
// If '.all' rejected, we've got the result we wanted.
(val) => { return Promise.resolve(val); }
);
// return the promise or reject it if timeout occur first
const timeoutPromise = (ms, promise) => new Promise(function(resolve, reject) {
setTimeout(() => reject(new Error('timeout')), ms);
promise.then(resolve, reject);
});
if (options.subsystems.length < 1) {
return Promise.reject('Parameters error, no subSystems specified');
}
const timedOutSubsystems = options.subsystems.map(function(subsystem){
return timeoutPromise(options.timeOutMs, subsystem(options));
});
const startDate = Date.now();
return oneSuccess(
timedOutSubsystems
)
.then((result) => {
const elapsedTime = Math.abs((startDate - Date.now()) / 1000);
console.log('firstThatCompleteSuccessfully() done, after s: ' + elapsedTime + ': '+ result);
return result;
})
.catch((error) => {
const elapsedTime = Math.abs((startDate - Date.now()) / 1000);
console.error('firstThatCompleteSuccessfully() error/nodata: ' + error);
});
}
const subsystem1 = (options) => new Promise(function(resolve, reject) {
setTimeout(function(){
console.log('subsystem1 finished');
resolve('subsystem 1 OK');
}, 1000);
});
const subsystem2 = (options) => new Promise(function(resolve, reject) {
setTimeout(function(){
console.log('subsystem2 finished');
resolve('subsystem 2 OK');
}, 2000);
});
firstThatCompleteSuccessfullyES6({
subsystems: [subsystem1, subsystem2],
timeOutMs: 2000
})
.then((result) => console.log("Finished: "+result));
@mircoc
Copy link
Author

mircoc commented Dec 13, 2017

Also available as JS Bin here:
http://jsbin.com/taqomot/edit?js,console

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment