티스토리 뷰

728x90

안녕하세요! 오늘은 자바스크립트의 프로미스에 대해서 알아보겠습니다.


1. 동기 vs 비동기

    코드는 기본적으로 동기적으로 실행됩니다. 동기적으로 실행된다는 말은 코드가 위에서부터 아래 순서대로 실행된다는 말입니다. 하지만 프로그래밍을 하다보면 코드 순서 상관없이 필요한 상황에 필요한 코드가 작동돼야하는 상황이 반드시 옵니다. 이때 코드를 병렬으로 처리하는 것이 비동기적으로 실행한다고 말합니다.

 

    비동기적으로 코드를 실행하려면 여러가지 방법이 있습니다. ajax, setTimeout, callback 와 같은 방법으로 개발자들은 비동기 처리를 진행합니다. 프로미스(promise)는 세 방법 중에서 callback을 해결하기 위해서 나타났습니다. 

 

//동기 : 1 2 3 
console.log(1); 
console.log(2);
console.log(3);

//비동기 : 1 3 (2초 뒤에) 2
console.log(1)
setTimeout(function(){console.log(2)},2000);
console.log(3)

2. Callback Hell 콜백 지옥

    Callback 지옥은 밑의 코드처럼 콜백함수가 반복돼서 들여쓰기가 감당 안될정도로 깊어지는 현상입니다. 주로 비동기 작업을 처리하기 위해 이런 형태가 자주 등장합니다. CallBack Hell은 가독성이 떨어지고, 코드를 수정하기 어려워진다는 단점이 있습니다.

 

    이런 콜백지옥을 해결하기 위해 등장한 것이 바로 프로미스입니다.

func1(function (value1) {
    func2(function (value2) {
        func3(function (value3) {
            func4(function (value4) {
                func5(function (value5) {
                    func6(function (value6) {
                    });
                });
            });
        });
    });
});

3. 프로미스 사용하기

    프로미스는 실행은 바로 하되 결괏값은 나중에 받는 객체입니다. 즉, 어떤 사건이 일어나면 그 결과(resolve or reject)에 따라, 어떤 코드(then or catch)를 실행시키기로 약속을 걸어놓는 작업입니다. 프로미스를 사용하려면 다음과 같이 하면 됩니다.

  1. 프로미스 객체 생성
    • new Promise로 프로미스 생성
    • resolve와 reject를 매개변수로 갖는 콜백함수 넣기
  2. .then, .catch, .finally 메서드 붙이기
    • then -> resolve가 호출됐을 경우 (성공)
    • catch -> reject가 호출됐을 경우 (실패)
    • finally -> 성공/실패 여부와 상관없이 실행
//프로미스 객체 생성
const promise=new Promise((resolve,reject)=>{
  if(true){
    resolve('성공');
  } else {
    reject('실패');
  }
});

//프로미스 실행
promise
  .then((res)=>{     //resolve 성공했을 경우
  	console.log(res);
  })
  .catch((err)=>{    //reject 실패했을 경우
  	console.log(err);
  })
  .finally(()=>{    //끝나고 무조건 실행
  	console.log('finally');
  });

3. 프로미스 응용하기 (1) -> 콜백 지옥 해결

    프로미스는 콜백 지옥을 해결하기 위해서 만들어졌습니다. 프로미스의 진가는 콜백이 계속 일어날때 나타납니다. 프로미스는 then에서 return값을 프로미스로 할 수 있습니다. 프로미스가 return 되면 다시 then으로 프로미스를 받아서 실행할 수 있습니다. 이런 과정 통해서 비동기처리를 콜백지옥 없이 할 수 있습니다. 

//콜백을 여러번하는 프로미스
promise
  .then((res)=>{    // 1.  
  	// 코드 실행
    return new Promise((resolve,reject)=>{
      resolve(res);
    });
  })
  .then((res2)=>{    // 2.
    //코드 실행
    return new Promise((resolve,reject)=>{
      resolve(res2);
    });
  })
  .then((res3)=>{    // 3.
    console.log(res3);
  }
  .catch((err)=>{    // 에러처리
  	console.log(err);
  });

4. 프로미스 응용하기 (2) -> fetch 활용

    프로미스를 사용할때 자기가 만든 프로미스 말고도 다른 사람이 만들어놓은 프로미스를 사용할 수 있습니다. 대표적인 예시로 fetch가 있습니다. fetch는 HTTP 파이프라인을 구성하는 요청과 응답 등의 요소를 JavaScript에서 접근하고 조작할 수 있도록 합니다. 프로미스를 공부하면서 생활코딩님의 유튜브 강의가 정말 많이 도움 됐습니다. 강의에서 fetch를 다루는 부분이 자세히 나오니 한번 보시면 좋을 것 같습니다.

https://www.youtube.com/watch?v=Sn0ublt7CWM 

    fetch를 사용해서 프로미스 작업을 한 예제입니다.

 

fetch("https://jsonplaceholder.typicode.com/posts")
  .then(res=>{
    return res.json(); //프로미스 반환
  })
  .catch(err=>{
    console.log('error : ',err);
  })
  .then(data=>{ //return res.join()의 then
      console.log('data : ',data);
  });

5. 프로미스 응용하기 (3) -> Promise.all, .resolve, .reject

    Promise.all은 프로미스 여러 개를 한 번에 실행할 때 사용합니다. 프로미스를 사용하지 않을 경우에는 콜백을 여러 번 중첩했을테지만, 프로미스를 사용하면 간단하게 구현할 수 있습니다.

    Promise.resolve는 즉시 resolve하는 프로미스를 만들 때 사용합니다. 프로미스가 여러개 있을 경우 모든 프로미스가 resolve될때까지 기다렸다가 then으로 넘어갑니다. result 매개변수에 각각의 프로미스 결과값이 배열로 들어가있습니다.

    Promise.reject도 마찬가지로 즉시 reject하는 프로미스를 만들 때 사용합니다. 

    

   만약, 프로미스가 여러개 있을 경우, 정확히 어떤 프로미스에서 reject 되었는지 알기 위해서 Promise.allSettled를 사용해야합니다. 

   

const p1=Promise.resolve('성공1')
const p2=Promise.resolve('성공2')

Promise.all([p1,r2])
  .then(res=>{
    console.log(res); //['성공1','성공2']
  })
  .catch(err=>{
    console.log(err);
  });

    이상으로 프로미스에 대해서 알아봤습니다. 프로미스를 공부하면서 Node.js 교과서를 참고했습니다. 감사합니다.

728x90
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함