체인의정석

Javascript) map에 Promise.all을 적용하여 동기화 시키기 본문

개발/backend

Javascript) map에 Promise.all을 적용하여 동기화 시키기

체인의정석 2022. 11. 18. 11:35
728x90
반응형

map안에 await를 걸어두게 되면 실제로 동기화가 되지 않는 상태로 작동하게 된다.

블로그 참고)

https://www.techiediaries.com/promise-all-map-async-await-example/

 

Promise.all() and map() with Async/Await by Example | Techiediaries

In this quick example, we'll learn how to use Promise.all() and map() with Async/Await in JavaScript to impelemt certain scenarios that can't be implemented with for loops with async/await. Example of JavaScript Promises that Rely on Each Other More often

www.techiediaries.com

 

 

먼저 동기 함수 2개를 만들어보자

// this promise depends on the result of the previous promise
const getProductId = (category) => {
  return new Promise((resolve, reject) => {
    return setTimeout(() => resolve(category.id), 1000)
  })
}

prodcut ID를 1초 후에 리턴해주는 함수와

const capitalizeId = (id) => {
  return new Promise((resolve, reject) => {
    return setTimeout(() => resolve(id.toUpperCase()), 700)
  })
}

id를 입력받아서 대문자로 만들어 주는 함수

 

이렇게 2개의 Promise 리턴 값을 주는 경우를 보자

 

그럼 여기안에서 for 루브를 돌면서 동기화를 처리시키려고 해본다면 동기화가 될까?

const capitalizeProductsIds = async () => {
  const products = await getProducts()

  for (let product of products) {
    const productId = await getProductId(product);
    console.log(productId);

    const capitalizedId = await capitalizeId(productId);
    console.log(capitalizedId);
  }

  console.log(products);
}

capitalizeProductsIds()

 

여기에 대한걸 보면 동기화가 되지 않아서 productID를 가져오는 부분부터 먼저 다 실행되고 그 다음에 이걸 대문자로 만들어주는 연산이 실행된 것을 볼 수 있다.

product1
PRODUCT1

product2
PRODUCT2

product3
PRODUCT3

product4
PRODUCT4

(4) [{…}, {…}, {…}, {…}]

그렇다면 promise.all + map을 같이 쓴다면?

const capitalizeProductsIds = async () => {
  const products = await getProducts()

  Promise.all(
    products.map(async (product) => {
      const productId = await getProductId(product);
      console.log(productId);

      const capitalizedId = await capitalizeId(productId)
      console.log(capitalizedId);
    })
  )

  console.log(products);
}
capitalizeProductsIds();

그 productID를 먼저 모두 계산한 후에 capitalizedID를 계산하는 것을 볼 수 있었다.

 

(4) [{…}, {…}, {…}, {…}]

product1
product2
product3
product4

PRODUCT1
PRODUCT2
PRODUCT3
PRODUCT4

이런 상황외에도 map을 사용했는데 Promise를 쓰고 싶다? 그러면 Promise.all을 쓰면 된다.

 

또한 promise all의 경우

만약 요소 중에 동기와 비동기가 섞여있는 경우에는 
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

 

Promise.all() - JavaScript | MDN

Promise.all() 메서드는 순회 가능한 객체에 주어진 모든 프로미스가 이행한 후, 혹은 프로미스가 주어지지 않았을 때 이행하는 Promise를 반환합니다. 주어진 프로미스 중 하나가 거부하는 경우, 첫

developer.mozilla.org

Promise 객체를 리턴하는 애들은 동기화 되어서 나오고 나머지 애들은 그냥 비동기로 실행이 된다고 한다.

또한 중간에 에러가 리턴되는 경우라면 에러가 발생하는 순간 중간에 에러가 나온다고 한다.

728x90
반응형
Comments