javascript - Using AsyncAwait vs Promise.all with for-loops - Stack Overflow

Here is how I understand things currently:asyncawait in a for-loop should pause execution until the pr

Here is how I understand things currently:

async/await in a for-loop should pause execution until the promise resolves, meaning that the next iteration of the loop won't occur until that line finishes.

Consider the following array:

const data = [];
for (let i = 0; i <= 100000; i++) {
    data.push(i);
}

Method 1: Awaiting Promises in a for-loop

async function method1() {
  const startTime = new Date();
  console.log('start:', startTime);

  for (const item in data) {
    await new Promise(resolve => {
      if (item % 3 === 0) {
        resolve({});
      } else {
        resolve(item)
      }
    });
  }

  const endTime = new Date();
  console.log('finish:', endTime);
  console.log('total time:', endTime-startTime);
}

Because it requires sequential execution of promises to continue through the loop, I figured using Promise.all would be a performance enhancement that leverages asynchronous processing to a greater degree:

Method 2: Promise.all following a for-loop

async function method2() {
  const promises = [];
  const startTime = new Date();
  console.log('start:', startTime);

  for (const item in data) {
    const promise = new Promise(resolve => {
      if (item % 3 === 0) {
        resolve({});
      } else {
        resolve(item)
      }
    });

    promises.push(promise);
  }

  await Promise.all(promises);
  const endTime = new Date();
  console.log('finish:', endTime);
  console.log('total time:', endTime-startTime);
}

My reasoning: the loop would continue to bang out new Promises while each previously created Promise attempts resolve. So in my head, method 1 = blocking... while method 2 = less blocking.

When I run these both on repl.it, I found that method method 1 is actually quicker, almost by a factor of 2. Can somebody explain why this is? Shouldn't it be the other way around?

Here is how I understand things currently:

async/await in a for-loop should pause execution until the promise resolves, meaning that the next iteration of the loop won't occur until that line finishes.

Consider the following array:

const data = [];
for (let i = 0; i <= 100000; i++) {
    data.push(i);
}

Method 1: Awaiting Promises in a for-loop

async function method1() {
  const startTime = new Date();
  console.log('start:', startTime);

  for (const item in data) {
    await new Promise(resolve => {
      if (item % 3 === 0) {
        resolve({});
      } else {
        resolve(item)
      }
    });
  }

  const endTime = new Date();
  console.log('finish:', endTime);
  console.log('total time:', endTime-startTime);
}

Because it requires sequential execution of promises to continue through the loop, I figured using Promise.all would be a performance enhancement that leverages asynchronous processing to a greater degree:

Method 2: Promise.all following a for-loop

async function method2() {
  const promises = [];
  const startTime = new Date();
  console.log('start:', startTime);

  for (const item in data) {
    const promise = new Promise(resolve => {
      if (item % 3 === 0) {
        resolve({});
      } else {
        resolve(item)
      }
    });

    promises.push(promise);
  }

  await Promise.all(promises);
  const endTime = new Date();
  console.log('finish:', endTime);
  console.log('total time:', endTime-startTime);
}

My reasoning: the loop would continue to bang out new Promises while each previously created Promise attempts resolve. So in my head, method 1 = blocking... while method 2 = less blocking.

When I run these both on repl.it, I found that method method 1 is actually quicker, almost by a factor of 2. Can somebody explain why this is? Shouldn't it be the other way around?

Share Improve this question edited Jun 5, 2020 at 17:02 stoneb asked Jun 5, 2020 at 16:56 stonebstoneb 531 silver badge5 bronze badges 1
  • 1 The conceptual difference between the two approaches is that one runs the asynchronous operations in parallel, the other runs them in serial. With fake asynchronous operations, you can't see the real effect of that difference. With real asynchronous operations, the effect would be obvious and running in parallel would have a way faster end-to-end time. If each asynchronous operation took 200ms to resolve, then method 1 would resolve in ~n * 200ms and method 2 would resolve in ~200ms where n is the number of async operations you run. – jfriend00 Commented Jun 5, 2020 at 17:52
Add a ment  | 

2 Answers 2

Reset to default 3

My guess is that you resolve too fast, so the looping dominates the execution time, since method2 has two loops: one to push to the array and one for promise.all to plete while method1 only has one loop, so your feeling "almost a factor of two" is actually theoretically correct.

Try faking an actual async operation like new Promise(resolve => setTimeout(resolve, 200)) and you should get what you expected

To add further to what Drake said. The only reason why method 2 is slower without timeouts is because of the number of loops it will have to encounter, but in a real scenario where request or asynchronous operations have delays. Method 2 will most of the time be faster

Here is the modified snippet with SetTimeout.

const data = [];
for (let i = 0; i <= 1000; i++) {
    data.push(i);
}


async function method1() {
  const startTime = new Date();
  console.log('start 1:', startTime);

  for (const item in data) {
   await new Promise(resolve => {
      setTimeout(()=>{
        if (item % 3 === 0) {
        resolve({});
      } else {
        resolve(item)
      }
      },1)
    });
  }
  const endTime = new Date();
  console.log('finish 1:', endTime);
  console.log('total time:', endTime-startTime);
}

async function method2() {
  const promises = [];
  const startTime = new Date();
  console.log('start 2:', startTime);

  for (const item in data) {
    const promise = new Promise(resolve => {
      setTimeout(()=>{
        if (item % 3 === 0) {
        resolve({});
      } else {
        resolve(item)
      }
      },1)
    });

    promises.push(promise);
  }

  await Promise.all(promises);
  const endTime = new Date();
  console.log('finish 2:', endTime);
  console.log('total time:', endTime-startTime);
}

method1()
method2()

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744142967a4560288.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信