forEach와 async await

citron03·2022년 9월 21일
0

html, css, js

목록 보기
42/43
  • forEach는 promises를 기다리지 않기에 async await 구문 역시 동작하지 않는다.
const setTimeoutPlus = (num1, num2) => {
  return new Promise((resolve, reject) => {
    try {
      setTimeout(() => {
        resolve(num1 + num2);
      }, 3000);
    } catch (e) {
      reject("ERROR", e);
    }
  })
}

const asyncForEachFuc = (data) => {
  let tmp = [];
  console.log("start", tmp);
  data.forEach(async function(element,index,array){
    tmp.push(await setTimeoutPlus(element + index));
  });
  console.log("end", tmp);
  return tmp;
}

console.log("print", asyncForEachFuc([1, 2, 3, 4, 5]));
  • 위의 코드는 start, end, print 모두 빈 배열이 출력된다.
const setTimeoutPlus = (num1, num2) => {
  return new Promise((resolve, reject) => {
    try {
      setTimeout(() => {
        resolve(num1 + num2);
      }, 3000);
    } catch (e) {
      reject("ERROR", e);
    }
  })
}

const asyncForEachFuc = async (data) => {
  let tmp = [];
  console.log("start", tmp);
  let index = 0;
  for(let i of data) {
    tmp.push(await setTimeoutPlus(i, index));
    index += 1;
  }
  console.log("end", tmp);
  return tmp;
}

asyncForEachFuc([1, 2, 3, 4, 5]).then(el => console.log("print", el));

  • 위의 코드는 start는 빈 배열이 출력되나, 시간이 지난 뒤 end와 print에 [1,3,5,7,9] 배열이 출력된다.
const setTimeoutPlus = (num1, num2) => {
  return new Promise((resolve, reject) => {
    try {
      setTimeout(() => {
        resolve(num1 + num2);
      }, 300);
    } catch (e) {
      reject("ERROR", e);
    }
  })
}

const asyncForEachFuc = async (data) => {
  let tmp = [];
  console.log("start", tmp);
  let index = 0;
  for await (i of data) {
    tmp.push(await setTimeoutPlus(i, index)); 
    index++;
  }
  console.log("end", tmp);
  return tmp;
}

asyncForEachFuc([1, 2, 3, 4, 5]).then(el => console.log("print", el));
  • 위와 같은 for await 구문도 있는데, for await는 비동기 iterators를 처리하는 데 적합하다. 중간에 promises가 reject되어도 처리가 계속 되기 때문이다.

  • 또한, 모든 요청을 하나씩 보내고 기다리는 작업을 반복하게 된다.

  • for of와 for await of는 비슷하게 작동하나, 명시적으로 순차적인 처리가 일어남을 나타낼 수 있게 for await of를 사용한다.

  • 대신에 Promise.all을 사용하면, 요청을 한 번에 보내고 reject시 에러를 받을 수 있다.

const setTimeoutPlus = (num1, num2) => {
  return new Promise((resolve, reject) => {
    try {
      setTimeout(() => {
        resolve(num1 + num2);
      }, 300);
    } catch (e) {
      reject("ERROR", e);
    }
  })
}

const asyncForEachFuc = async (data) => {
  let tmp = [];
  console.log("start", tmp);
  tmp = await Promise.all(data.map((el, index) => setTimeoutPlus(el, index)));
  console.log("end", tmp);
  return tmp;
}

asyncForEachFuc([1, 2, 3, 4, 5]).then(el => console.log("print", el));
  • Promise.all은 요청을 한 번에 보내기에 for문보다 빠르게 처리된다.

참고 자료 : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach, https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/for-await...of, https://stackoverflow.com/questions/59694309/for-await-of-vs-promise-all, https://stackoverflow.com/questions/71100058/why-eslint-no-await-in-loop-not-working-with-for-await-of

profile
🙌🙌🙌🙌

0개의 댓글