简体   繁体   中英

Promise.all get slowest resolving promises

I have a few hundreds of things to render in parallel in an html5 canvas. These are drawn in parallel in a Promise.all call. Now, I would like to know which of these promise is the last to be resolved.


// get a promise that will resolve in between 0 and 5 seconds.
function resolveAfterSomeTime(): Promise<void> {
    return new Promise((resolve) => setTimeout(resolve, Math.random() * 5000));
}

const myPromises = [];
for (let i = 0; i < 100; i++) {
    myPromises.push(resolveAfterSomeTime);
}

Promise.all(myPromises).then(() => {
    // find out which promise was the last to resolve.
})

In my case, I have multiple classes with each a render() function. Some of these are heavier than others, but I want to know which ones.

I have something along these lines, and I would like to know which promise is the slowest to resolve, so that I can optimise it.

The best way I can think of is to use a counter indicating the number of promises that have resolved so far:

 function resolveAfterSomeTime() { return new Promise((resolve) => setTimeout(resolve, Math.random() * 5000)); } const myPromises = []; let resolveCount = 0; for (let i = 0; i < 100; i++) { myPromises.push( resolveAfterSomeTime().then(() => { resolveCount++; if (resolveCount === 100) { console.log('all resolved'); console.log('array item', i, 'took longest'); } }) ); }

Here's a way where each promise sets the value of lastPromiseToResolve after resolving. The last promise to resolve would set it last.


// get a promise that will resolve in between 0 and 5 seconds.
function resolveAfterSomeTime(): Promise<void> {
    return new Promise((resolve) => setTimeout(resolve, Math.random() * 5000));
}

let lastPromiseToResolve = null
const myPromises = [];
for (let i = 0; i < 100; i++) {
    const promise = resolveAfterSomeTime()
    myPromises.push(promise.then(() => {
        lastPromiseToResolve = promise // all the promises will set lastPromiseToResolve
    }));
}

Promise.all(myPromises).then(() => {
  console.log(lastPromiseToResolve) // this would be the last promise to resolve
})

You could time each promise. You could even assign an identifier to each one if you want to know specifically which is resolving. The timePromise function below takes an id and a function that returns a promise, times that promise, and logs the result. It doesn't change the result of the promises, so you can use myPromises as you normally would.

 function resolveAfterSomeTime() { return new Promise((resolve) => setTimeout(resolve, Math.random() * 1000)); } // f is a function that returns a promise function timePromise(id, f) { const start = Date.now() return f().then(x => { const stop = Date.now() console.log({id, start, stop, duration: (stop - start)}) return x }) } const myPromises = []; for (let i = 0; i < 100; i++) { myPromises.push(timePromise(i, resolveAfterSomeTime)); } Promise.all(myPromises).then(() => { // find out which promise was the last to resolve. })

I'm not sure how you're creating your array of promises in your actual code, so it might not be straightforward to wrap each promise in a function that returns it. But you could likely adapt this to work with your situation.

If you aren't concerned with knowing exactly how long each takes, you could just have timePromise take a promise that's already started, and time from when timePromise is called to when it resolves. This wouldn't be as accurate, but would still give you a general idea, especially if one or a few promises are taking much longer than others.

Something like this:

function timePromise(id, p) {
  const start = Date.now()
  
  return p
    .then(x => {
      const stop = Date.now()
      
      console.log({id, start, stop, duration: (stop - start)})
      return x
    })
}

const myPromises = [];
for (let i = 0; i < 100; i++) {
    myPromises.push(timePromise(i, resolveAfterSomeTime()));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM