Last active
December 13, 2017 14:17
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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)); |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Also available as JS Bin here:
http://jsbin.com/taqomot/edit?js,console