All posts by freesens

[JS] forEach 사용시 async 함수 호출

최근에 업무중 forEach로 순회하며 api 호출 후 결과를 받아서 다음 작업을 수행해야하는 경우가 있었다.

일단 api가 list형태로 파라미터를 던져서 한번에 조회 결과를 반환해주면 성능 면에서 더 좋을텐데, 굳이 단건 호출만 가능하도록 api를 제공하니 어쩔 수 없이 forEach로 순회하며 여러번 api를 호출할 수 밖에 없었다.

어쨋든 의도는 forEach로 순회하며, async 함수로 api를 호출 후 결과를 받아서 값을 셋팅해야 하는데, 돌려보니 비동기 호출 후 결과가 오기를 기다리지 않고 그냥 다음 순회를 돌아버리는 문제가 있었다.

forEach() expects a synchronous function — it does not wait for promises. Make sure you are aware of the implications while using promises (or async functions) as forEach callbacks.

mdn web docs를 찾아보니 forEach는 promises를 기다리지 않는다고 한다.

그래서 더 찾아보니 for of문을 이용하는 방법이 있는데, 이 방법은 순차적으로 처리하다 보니 병렬처리가 아니라서 순회건수가 많으면 시간이 오래걸리는 문제가 있고,

병렬처리를 위해서는 Promise.all()을 이용하는 방법이 있다.

비동기로 호출해야 하는 api 호출 부분을 Promise배열로 만들고, Promise.all()을 통해 실행하면 비동기 함수들을 병렬로 동시에 처리할 수 있다.

let apis = [];

const promises = this.sourceList.map(async (x) => {
const api = await calledApi({key: x.value});
apis.push(api);
});

await Promise.all(promises);

map()을 통해서 promise배열에 담아서, Promise.all()을 통해 실행할 수 있다.

결론은 순회하면서 비동기 처리가 필요하면 forEach대신에 map(async obj) 형태로 사용하면 된다.

Gitlab ERROR 422 The change you requested was rejected.

잘 사용하던 gitlab 로그인이 풀려서 다시 로그인을 하니 아래와 같은 화면만 나온다.

id/password는 틀리지 않고 제대로 입력했고, 뭔가 내 요청이 바뀌어서 거절됐다는데 …

크롬에서 ctrl + shift + n을 눌러서 시크릿모드로 열어서 gitlab 로그인을 해보니 잘 된다.

시크릿모드에서는 잘 되는 것으로 보아 gitlab도 문제는 없는거 같고.

시크릿모드와 같은 깨끗한(?) 상태로 접근하기 위해 크롬 설정에서 gitlab 접근 도메인의 쿠키 및 캐시데이터를 전부 삭제하고 시도하니 잘된다.