Array.map()에서의 비동기 처리

이지용·2022년 11월 10일
0

TIL

목록 보기
1/4

간단한 커뮤니티를 만드는 사이드 프로젝트를 진행하고 있는데, 예상치도 못한 곳에서 작업이 막혔다. DB에서 게시글과 댓글 정보를 가져오는 과정에서 비동기 처리를 해야 하는데, 게시글 객체의 배열에 map() 메서드를 사용해 각 게시글의 댓글을 불러오는 과정에서 계속 프로미스의 배열이 반환된다는 거다.

분명 도큐먼트의 배열이었던 것이

프로미스 배열이 돼버렸다.

내용물이 프로미스 객체니 당연히 로그도 이상하게 나온다.

혹시 몰라 콜백 함수를 async 함수로 바꿔 봤지만 여전히 프로미스를 반환한다.

async function appendComments(article) {
  const articleId = article._id.toString();

  const query = { articleId };
  const options = { createdAt: -1, projection: { articleId: 0 } };

  const comments = await db
    .collection('comments')
    .find(query, options)
    .toArray();

  if (comments.length) {
    const newArticle = Object.assign(article, { comments });

    return newArticle;
  }
  return article;
}

알고보니 appendComments() 함수를 async 함수로 선언했던 게 문제였다...
iterable을 비동기로 처리하다 보니 map() 메서드가 결과를 기다리지 않고 그대로 프로미스를 반환하는 건데 해결 방법은 간단했다.

바로 Promise.all() 메서드를 사용하면 해결된다. 그러면 콜백 함수에서 호출된 async appendComments() 함수가 모두 처리될 때까지 기다리고 처리된 결과가 반환된다.

문제가 된 부분을 Promise.all() 메서드로 감싸주니 VSCode가 일반 객체의 배열이 반환될 거라고 얘기해준다.

물론 내용물도 아주 잘 출력됐다.

혼자서는 도저히 해결할 수 없어서 포기하고 다른 방법을 찾아보려 했는데, 다른 분의 도움으로 매우 쉽게 해결됐는데, 아무래도 비동기 작업에 대해 이해가 더 필요한 것 같으니 열심히 공부해야겠다.

참고한 글 - https://velog.io/@jing07161/TIL-35-map%EC%97%90%EC%84%9C%EC%9D%98-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%B2%98%EB%A6%AC

0개의 댓글