Hello is there any solution to order promises by execution time? for ex
Promise.all([Promise // 5ms ,Promise // 3ms,Promise // 2ms])
will return answer with same order as it was given is there any solution or method to sort it by execution time to have return like?
Promise.all([Promise // 2ms ,Promise // 3ms,Promise // 5ms])
To restate the problem clearly: given a set of promises, can they be executed concurrently, and can the results be arranged in an array in order of execution time?
If the execution time is known in advance, then sort the promises by execution time and pass the sorted array to Promise.all().
If the execution times are unknown in advance, I'd suggest wrapping the promises with a little function that times execution. Sort the result of Promise.all() on those elapsed times...
function sortedPromiseAll(array) {
const start = new Date()
const instrumentPromise = p => {
return p.then(result => {
const now = new Date();
return { result, duration: now.getTime()-start.getTime() }
});
}
const instrumentedPromises = array.map(instrumentPromise)
return Promise.all(instrumentedPromises).then(results => {
return results.sort((a, b) => a.duration-b.duration).map(r => r.result);
})
}
const timedPromise = t => {
return new Promise(resolve => {
setTimeout(resolve, t)
})
};
// imagine we don't know these timings
const promiseA = timedPromise(600).then(() => 'A');
const promiseB = timedPromise(300).then(() => 'B');
const promiseC = timedPromise(900).then(() => 'C');
// expected result is B, A, C
sortedPromiseAll([promiseA, promiseB, promiseC])
.then(result => console.log(result));
You can get the ordering of when they resolve if you manually push the results of each promise into an array. In this example the value resolved is a string that shows the timestamp it was added.
Results are pushed into outputs array when they resolve. Printing outputs shows they are now ordered based on when they resolved.
const outputs = [];
function createPromise() {
return new Promise((resolve, reject) => {
// adding a bit of randomness here so there is no guarantee when they resolve
const delay = Math.random() * 1000;
setTimeout(() => {
resolve(`Promise resolved at ${Date.now()}`);
}, delay);
});
}
function addResult() {
return createPromise().then(value => {
outputs.push(value);
});
}
Promise.all([addResult(), addResult()]).then(() => console.log(outputs));
The easiest way is to push them to a new array as they come in. No need to create extra promises, just have to piggyback off the promise that is already created.
const getRandomPromise = () => {
return new Promise(resolve => {
var ms = Math.random() * 3000;
window.setTimeout(()=>resolve(ms), ms);
});
};
function orderPromises (promises) {
const orderedPromies = [];
const pushPromiseResults = promise =>
promise.then(result => (orderedPromies.push(result), result))
promises.forEach(pushPromiseResults);
return Promise.all(promises).then(()=>orderedPromies);
}
const myPromises = [getRandomPromise(), getRandomPromise(), getRandomPromise()];
orderPromises(myPromises).then(x => console.log(x));