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

时间:2021-04-17 23:44:56

标签: javascript typescript promise promise.all

我有几百个东西要在 html5 画布中并行渲染。这些在 Promise.all 调用中并行绘制。现在,我想知道这些承诺中哪一个是最后一个要解决的。


// 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.
})

就我而言,我有多个类,每个类都有一个 render() 函数。其中一些比其他的重,但我想知道哪些。

我有一些类似的问题,我想知道哪个 promise 的解决速度最慢,以便我可以对其进行优化。

3 个答案:

答案 0 :(得分:4)

我能想到的最好方法是使用一个计数器来指示到目前为止已解决的承诺数量:

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');
        }
      })
  );
}

答案 1 :(得分:4)

以下是每个 promise 在解析后设置 lastPromiseToResolve 值的方法。最后一个要解决的承诺会将其设置为最后。


// 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
})

答案 2 :(得分:2)

您可以为每个承诺计时。如果您想具体知道哪个正在解析,您甚至可以为每个标识符分配一个标识符。下面的 timePromise 函数接受一个 id 和一个返回承诺、承诺时间并记录结果的函数。它不会改变承诺的结果,因此您可以像往常一样使用 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.
})

我不确定您是如何在实际代码中创建承诺数组的,因此将每个承诺包装在返回它的函数中可能并不简单。但您可能会根据自己的情况调整它。

如果您不关心确切知道每个需要多长时间,您可以让 timePromise 接受一个已经开始的承诺,以及从 timePromise 被调用到它解决的时间。这不会那么准确,但仍可为您提供一个大致的概念,尤其是当一个或几个承诺比其他承诺花费的时间要长得多的情况下。

像这样:

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()));
}
相关问题