简体   繁体   English

Promise.all 得到最慢的解决承诺

[英]Promise.all get slowest resolving promises

I have a few hundreds of things to render in parallel in an html5 canvas.在 html5 canvas 中,我有数百件东西要并行渲染。 These are drawn in parallel in a Promise.all call.这些在Promise.all调用中并行绘制。 Now, I would like to know which of these promise is the last to be resolved.现在,我想知道这些 promise 中的哪一个是最后被解决的。


// 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.就我而言,我有多个类,每个类都有一个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.我有这些方面的东西,我想知道哪个 promise 解决起来最慢,以便我可以优化它。

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.这是每个lastPromiseToResolve在解析后设置lastPromiseToResolve的值的一种方式。 The last promise to resolve would set it last.最后一个要解析的 promise 会将其设置为最后一个。


// 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.您可以为每个 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.下面的timePromise function 需要一个 id 和一个 function,它返回一个 promise,结果是 promise 的倍数,结果是 ZB321DE3BDCDE799EC8。 It doesn't change the result of the promises, so you can use myPromises as you normally would.它不会改变 Promise 的结果,因此您可以像往常一样使用myPromises

 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.我不确定您是如何在实际代码中创建承诺数组的,因此将每个 promise 包装在返回它的 function 中可能并不简单。 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.如果您不关心确切知道每个需要多长时间,您可以让timePromise获取一个已经启动的 promise,以及从调用timePromise到它解决的时间。 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()));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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