본문 바로가기
Language/JavaScript

[JS] forEach에서 비동기 함수 사용 금지!

by developerBeluga 2022. 9. 29.
728x90
반응형

 

 

 

상황

forEach 함수를 이용하여 배열 안에 있는 id로 axios를 사용할 생각이었습니다.

하지만 아무리 해도 원하는 상태값이 되지 않는 것이었습니다.

 

위와 같이 postmam으로 실행했을 때 해당 API 결과 값으로 빈 배열이 나옵니다.

원래였다면 아래에 있는 1, 2라는 숫자를 담아져 있는 [1, 2]가 나와야 했습니다.

 

 

 

원인

이유는 바로 forEach 함수는 콜백 함수로 비동기 함수를 받더라도 실행을 기다려주지 않는다고 합니다!

Javascript 공식문서에 적혀있는데 역시 공식문서로 정보를 확인해야 합니다.

공식문서 바로가기 : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

 

Array.prototype.forEach() - JavaScript | MDN

The forEach() method executes a provided function once for each array element.

developer.mozilla.org

 

 

 

 

해결

그럼 어떻게 해결하는 것이 좋을까요? 

방법은 아래와 같이 두가지입니다.

 

1. for...of 문

const array1 = ['a', 'b', 'c'];

for (const element of array1) {
  console.log(element);
}

// expected output: "a"
// expected output: "b"
// expected output: "c"

대안으로 for...of 문을 사용하시면 됩니다. 

하지만 forEach()처럼 병렬 처리로 진행하지 않기 때문에 소요 시간이 길어질 수 있습니다.

 

 

2. Promise.all()

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values);
});
// expected output: Array [3, 42, "foo"]

쇼요 시간이 길다면 forEach처럼 병렬 처리로 진행하는 Promise.all()을 추천해드립니다.

주어진 프로미스 중 하나라도 거부되면, 다른 프로미스의 이행 여부와 상관없이 첫 번째 거부 이유로 사용이 중지됩니다.

 

 

 

하지만..!

상황에서도 설명했다싶이 저는 axios를 통해 다른 서비스와의 통신이 필수이며 코드 로직상 Promise.all 대신 for...of문이 더 낫다고 판단하였습니다.

여러분들도 자신의 상황에 맞는 방안으로 선택하여 개발하시길 바랍니다.

 

 

 

 

 

728x90
반응형

댓글