programing

wait Promise.all()과 multiple wait 사이에 어떤 차이가 있습니까?

procenter 2022. 10. 10. 20:59
반응형

wait Promise.all()과 multiple wait 사이에 어떤 차이가 있습니까?

다음 사이에 차이가 있습니까?

const [result1, result2] = await Promise.all([task1(), task2()]);

그리고.

const t1 = task1();
const t2 = task2();

const result1 = await t1;
const result2 = await t2;

그리고.

const [t1, t2] = [task1(), task2()];
const [result1, result2] = [await t1, await t2];

주의:

은 단지 뿐입니다.awaitPromise.all@mikep의 포괄적인 답변을 읽어보시기 바랍니다.또, 에러 처리의 보다 중요한 차이도 다루고 있습니다.


이 답변에서는 몇 가지 예시 방법을 사용합니다.

  • res(ms)는 밀리초의 정수가 걸려 그 밀리초 후에 해결되는 약속을 반환하는 함수입니다.
  • rej(ms)는 밀리초의 정수가 걸려 그 수 밀리초 후에 거부된 약속을 반환하는 함수입니다.

" "res타이머를 기동합니다.「」를 사용합니다.Promise.all 지연이것을 하십시오.

예 #1
const data = await Promise.all([res(3000), res(2000), res(1000)])
//                              ^^^^^^^^^  ^^^^^^^^^  ^^^^^^^^^
//                               delay 1    delay 2    delay 3
//
// ms ------1---------2---------3
// =============================O delay 1
// ===================O           delay 2
// =========O                     delay 3
//
// =============================O Promise.all

async function example() {
  const start = Date.now()
  let i = 0
  function res(n) {
    const id = ++i
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve()
        console.log(`res #${id} called after ${n} milliseconds`, Date.now() - start)
      }, n)
    })
  }

  const data = await Promise.all([res(3000), res(2000), res(1000)])
  console.log(`Promise.all finished`, Date.now() - start)
}

example()

, ,,Promise.all3초 후에 내부 약속의 데이터로 해결됩니다.

단, "fail fast" 동작은 다음과 같습니다.

예 #2
const data = await Promise.all([res(3000), res(2000), rej(1000)])
//                              ^^^^^^^^^  ^^^^^^^^^  ^^^^^^^^^
//                               delay 1    delay 2    delay 3
//
// ms ------1---------2---------3
// =============================O delay 1
// ===================O           delay 2
// =========X                     delay 3
//
// =========X                     Promise.all

async function example() {
  const start = Date.now()
  let i = 0
  function res(n) {
    const id = ++i
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve()
        console.log(`res #${id} called after ${n} milliseconds`, Date.now() - start)
      }, n)
    })
  }
  
  function rej(n) {
    const id = ++i
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        reject()
        console.log(`rej #${id} called after ${n} milliseconds`, Date.now() - start)
      }, n)
    })
  }
  
  try {
    const data = await Promise.all([res(3000), res(2000), rej(1000)])
  } catch (error) {
    console.log(`Promise.all finished`, Date.now() - start)
  }
}

example()

「 」를 사용하고 async-await대신 각 약속이 순차적으로 해결될 때까지 기다려야 합니다.이치

예 3
const delay1 = res(3000)
const delay2 = res(2000)
const delay3 = rej(1000)

const data1 = await delay1
const data2 = await delay2
const data3 = await delay3

// ms ------1---------2---------3
// =============================O delay 1
// ===================O           delay 2
// =========X                     delay 3
//
// =============================X await

async function example() {
  const start = Date.now()
  let i = 0
  function res(n) {
    const id = ++i
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve()
        console.log(`res #${id} called after ${n} milliseconds`, Date.now() - start)
      }, n)
    })
  }
  
  function rej(n) {
    const id = ++i
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        reject()
        console.log(`rej #${id} called after ${n} milliseconds`, Date.now() - start)
      }, n)
    })
  }
  
  try {
    const delay1 = res(3000)
    const delay2 = res(2000)
    const delay3 = rej(1000)

    const data1 = await delay1
    const data2 = await delay2
    const data3 = await delay3
  } catch (error) {
    console.log(`await finished`, Date.now() - start)
  }
}

example()

첫 번째 차이 - Fail Fast

@@zzBov의 fast 장점은 ' fast'입니다Promise.all유일한 차이는 아닙니다.에 '왜'를 쓰느냐고 도 있어요.Promise.all부정적인 시나리오(일부 태스크가 실패했을 때)에서만 더 빠를 때 가치가 있습니다. 태스크가 매우오류 를 받기 더 긴까지 사용자가 하는 이유는 입니까?2개의 독립된 비동기 병렬 태스크가 있는데 첫 번째 태스크가 해결에 매우 오랜 시간이 걸렸지만 두 번째 태스크가 매우 짧은 시간에 거부된 경우 오류 메시지를 받기 위해 더 긴 콜이 완료될 때까지 사용자가 대기하도록 하는 이유는 무엇입니까?실제 응용 프로그램에서는 부정적인 시나리오를 고려해야 합니다. OK - 이 첫 에서는 어떤 할 수 .Promise.all 복수await.

두 번째 차이 - 오류 처리

처리를 할 때는 에러 처리를 사용해야 합니다.Promise.all. 할 수 await s로 .UnhandledPromiseRejectionWarning ★★★★★★★★★★★★★★★★★」PromiseRejectionHandledWarningtry/namebase를 어디에 사용하든 그게 이유다Promise.all을 사용하다는 ''를 사용해서 할 수 할 수 .process.on('unhandledRejection', err => {}) ★★★★★★★★★★★★★★★★★」process.on('rejectionHandled', err => {})을 사용법저는 인터넷에서 두 개 이상의 독립적인 비동기 병렬 태스크에 대한 오류 처리를 전혀 고려하지 않거나 잘못된 방식으로 고려하는 많은 예를 발견했습니다. 시도하다여기서 좋은 관행을 찾는 것은 거의 불가능하다.

요약

TL을 .DR: 중중중 dr dr dr drawait에러를 올바르게 처리할 수 없기 때문에, 2개 이상의 독립된 비동기 병렬 태스크의 경우. 「」를 사용합니다.Promise.all()를 참조해 주세요.

비동기/await약속하다는 「 style 때문에, 「sync style」이 복수인 것은 수 .then속에에있있있있

사용할 때 이렇게 말하는 사람도 있습니다.Promise.all()작업 오류를 개별적으로 처리할 수 없으며 첫 번째 거부된 약속에서 오류를 처리할 수 있을 뿐입니다(로그에 도움이 되는 경우 등).이것은 문제가 아닙니다.이 답변 하단의 "추가" 제목을 참조하십시오.

이 비동기 작업을 고려하십시오.

const task = function(taskNum, seconds, negativeScenario) {
  return new Promise((resolve, reject) => {
    setTimeout(_ => {
      if (negativeScenario)
        reject(new Error('Task ' + taskNum + ' failed!'));
      else
        resolve('Task ' + taskNum + ' succeed!');
    }, seconds * 1000)
  });
};

, "는 차이가 .Promise.all 여러 개의 " " "await두 예 모두 s로 .Task 1 succeed! Task 2 succeed!5월 15일

// Promise.all alternative
const run = async function() {
  // tasks run immediate in parallel and wait for both results
  let [r1, r2] = await Promise.all([
    task(1, 5, false),
    task(2, 5, false)
  ]);
  console.log(r1 + ' ' + r2);
};
run();
// at 5th sec: Task 1 succeed! Task 2 succeed!
// multiple await alternative
const run = async function() {
  // tasks run immediate in parallel
  let t1 = task(1, 5, false);
  let t2 = task(2, 5, false);
  // wait for both results
  let r1 = await t1;
  let r2 = await t2;
  console.log(r1 + ' ' + r2);
};
run();
// at 5th sec: Task 1 succeed! Task 2 succeed!

단, 첫 번째 작업이 10초 걸리고 성공하며 두 번째 작업이 5초 걸렸지만 실패하면 오류 발생에 차이가 있습니다.

// Promise.all alternative
const run = async function() {
  let [r1, r2] = await Promise.all([
      task(1, 10, false),
      task(2, 5, true)
  ]);
  console.log(r1 + ' ' + r2);
};
run();
// at 5th sec: UnhandledPromiseRejectionWarning: Error: Task 2 failed!
// multiple await alternative
const run = async function() {
  let t1 = task(1, 10, false);
  let t2 = task(2, 5, true);
  let r1 = await t1;
  let r2 = await t2;
  console.log(r1 + ' ' + r2);
};
run();
// at 5th sec: UnhandledPromiseRejectionWarning: Error: Task 2 failed!
// at 10th sec: PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)
// at 10th sec: UnhandledPromiseRejectionWarning: Error: Task 2 failed!

.await를 병렬로 합니다.에러를 처리해 보겠습니다.

// Promise.all alternative
const run = async function() {
  let [r1, r2] = await Promise.all([
    task(1, 10, false),
    task(2, 5, true)
  ]);
  console.log(r1 + ' ' + r2);
};
run().catch(err => { console.log('Caught error', err); });
// at 5th sec: Caught error Error: Task 2 failed!

오류를 하려면 '하다', '1'에 한.run콜백에 캐치 로직을 가진 코드를 추가합니다.는, 에러에 는 취급할 .run되기 때문에 기능 - - 약속 - 비동기 함수task에 의해 합니다.run★★★★★★ 。

stylesync/sync/sync/sync)을 합니다.await + 도잡/잡잡)
try { await run(); } catch(err) { }
이 안 못요.await메인 스레드에서 - 비동기 기능에서만 사용할 수 있습니다(아무도 메인 스레드를 차단하고 싶어하지 않기 때문입니다).이 「 스타일」로 하려면 , 「동기 스타일」에 해 주세요.run다른 비동기 함수의 함수 또는 IIE(즉시 호출된 함수 표현: MDN)를 사용합니다.

(async function() { 
  try { 
    await run(); 
  } catch(err) { 
    console.log('Caught error', err); 
  }
})();

이것이 두 개 이상의 비동기 병렬 태스크를 실행하여 오류를 처리하는 올바른 방법입니다.다음 예시는 피해야 합니다.

나쁜 예

// multiple await alternative
const run = async function() {
  let t1 = task(1, 10, false);
  let t2 = task(2, 5, true);
  let r1 = await t1;
  let r2 = await t2;
  console.log(r1 + ' ' + r2);
};

위의 코드의 에러는 몇 가지 방법으로 처리하려고 합니다.

try { run(); } catch(err) { console.log('Caught error', err); };
// at 5th sec: UnhandledPromiseRejectionWarning: Error: Task 2 failed!
// at 10th sec: UnhandledPromiseRejectionWarning: Error: Task 2 failed!
// at 10th sec: PromiseRejectionHandledWarning: Promise rejection was handled 

코드를 하기 때문에 도 잡히지 만...동기 코드를 처리하기 때문에 아무것도 잡히지 않았습니다만,run동기입입니니다

run().catch(err => { console.log('Caught error', err); });
// at 5th sec: UnhandledPromiseRejectionWarning: Error: Task 2 failed!
// at 10th sec: Caught error Error: Task 2 failed!
// at 10th sec: PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)

...응?...?? 되지 않은 알 수 있습니다작업 2의 에러가 처리되지 않은 것을 먼저 확인하고 나중에 검출한 것을 확인합니다.콘솔에 오류가 가득하고 오해의 소지가 있기 때문에 이 방법으로는 사용할 수 없습니다.

(async function() { try { await run(); } catch(err) { console.log('Caught error', err); }; })();
// at 5th sec: UnhandledPromiseRejectionWarning: Error: Task 2 failed!
// at 10th sec: Caught error Error: Task 2 failed!
// at 10th sec: PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)

@되지 않는 했습니다.삭제된 답변에서 사용자 @Qwerty는 오류가 검출된 것처럼 보이지만 처리되지 않은 이 이상한 동작에 대해 질문했습니다.은, 「」가 원인이 되어 .run()await하면 try/하여 try/catch를 할 수 .run()또한 비동기 태스크 함수를 동시에 호출하고 있기 때문에 처리되지 않은 오류가 발생합니다.await및 이 한다.run()★★★★★★ 。
이는 setTimeout을 호출하는 동기 함수를 호출할 때 try/catch를 통해 오류를 처리할 수 없는 경우와 유사합니다.

function test() {
  setTimeout(function() { 
    console.log(causesError); 
    }, 0);
}; 
try { 
  test(); 
} catch(e) { 
  /* this will never catch error */ 
}`.

또 다른 나쁜 예:

const run = async function() {
  try {
    let t1 = task(1, 10, false);
    let t2 = task(2, 5, true);
    let r1 = await t1;
    let r2 = await t2;
  }
  catch (err) {
    return new Error(err);
  }
  console.log(r1 + ' ' + r2);
};
run().catch(err => { console.log('Caught error', err); });
// at 5th sec: UnhandledPromiseRejectionWarning: Error: Task 2 failed!
// at 10th sec: PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)

... 2개의 에러(세 번째 에러는 누락)만 검출되지만, 아무것도 검출되지 않습니다.

추가(별도의 태스크 오류 및 최초 실패 오류 처리)

const run = async function() {
  let [r1, r2] = await Promise.all([
    task(1, 10, true).catch(err => { console.log('Task 1 failed!'); throw err; }),
    task(2, 5, true).catch(err => { console.log('Task 2 failed!'); throw err; })
  ]);
  console.log(r1 + ' ' + r2);
};
run().catch(err => { console.log('Run failed (does not matter which task)!'); });
// at 5th sec: Task 2 failed!
// at 5th sec: Run failed (does not matter which task)!
// at 10th sec: Task 1 failed!

에서는 어떤 이 일어나는지 더 잘 두 작업을 했습니다(...).이 예에서는 어떤 일이 일어나는지 더 잘 보여주기 위해 두 가지 작업을 모두 거부했습니다.throw err최종 에러를 발생시키기 위해서 사용됩니다).

Promise.all()는 요구 "syslogc"를 병렬로 실행합니다.「」를 사용합니다.await병렬로 실행하거나 "동기" 차단할 수 있습니다.

아래 test1 및 test2 함수는 다음 방법을 보여줍니다.await는 비동기 또는 동기화를 실행할 수 있습니다.

test3는 을 나타냅니다.Promise.all()동기입입니니다

jsfiddle with timed results - 브라우저 콘솔을 열어 테스트 결과를 확인합니다.

동기 동작병렬로 실행되지 않고 최대 1800ms 소요:

const test1 = async () => {
  const delay1 = await Promise.delay(600); //runs 1st
  const delay2 = await Promise.delay(600); //waits 600 for delay1 to run
  const delay3 = await Promise.delay(600); //waits 600 more for delay2 to run
};

비동기 동작병렬로 실행되며 최대 600ms 소요:

const test2 = async () => {
  const delay1 = Promise.delay(600);
  const delay2 = Promise.delay(600);
  const delay3 = Promise.delay(600);
  const data1 = await delay1;
  const data2 = await delay2;
  const data3 = await delay3; //runs all delays simultaneously
}

비동기 동작병렬 실행, 최대 600ms 소요:

const test3 = async () => {
  await Promise.all([
  Promise.delay(600), 
  Promise.delay(600), 
  Promise.delay(600)]); //runs all delays simultaneously
};

TLDR을 경우; TLDR:Promise.all()또한 포함된 기능의 첫 번째 장애 발생 시 "fast-fail" - 실행을 중지합니다.

직접 확인하실 수 있습니다.

바이올린에서, 나는 테스트를 실행했다.await가 , 「 」입니다.Promise.all모든 약속을 시작하고 기다리는 동안 다른 약속들과 함께 진행됩니다.

wait Promise.all([task1(), task2()]), "task1()" 및 "task2()"는 병렬로 실행되며 두 약속이 모두 완료될 때까지 기다립니다(해결되거나 거부됩니다).반면, 의 경우

const result1 = await t1;
const result2 = await t2;

t2는 t1의 실행이 완료된 후에만 실행됩니다(해결되었거나 거부됨).t1과 t2는 모두 병렬로 동작하지 않습니다.

언급URL : https://stackoverflow.com/questions/45285129/any-difference-between-await-promise-all-and-multiple-await

반응형