본문 바로가기
웹 프론트엔드/자바스크립트 (ES6)

[ES6] 기존 javascript 비동기 방식과 새로운 Promise 함수

by 지구인한군 2020. 12. 7.

2020.12.07 - [웹 프론트엔드/자바스크립트] - [ES6] 기존 javascript 비동기 방식과 새로운 Promise 함수

 


 어떤 프로그램 언어를 불문하고 비동기 처리는 중요합니다. 특히 웹 환경에서는 서버와의 잦은 통신으로 비동기 처리가 필수라고 할 수 있습니다. 그래서 오늘은 기존 자바스크립트의 비동기 방식과 새로운 Promise 함수를 비교하겠습니다.

 

먼저 총 4개의 프로세스가 있고 3개는 비동기 처리를, 나머지 하나는 즉시 호출하는 예로 코딩해보겠습니다.

 

// 기존 자바스크립트 방식
function process1(onFin){
  setTimeout(function(){onFin('프로세스1 완료')}, 1000);
}

function process2(onFin){
  setTimeout(function(){onFin('프로세스2 완료')}, 2000);
}

function process3(onFin){
  setTimeout(function(){onFin('프로세스3 완료')}, 3000);
}

function pri_process(){
  console.log('우선 순위 작업 완료');
}

process1(function(proc1){
  console.log('1초 뒤에 ' + proc1);
  process2(function(proc2){
    console.log('3초 뒤에 ' + proc2);
    process3(function(proc3){
      console.log('6초 뒤에 ' + proc3);
    });
  });
});

pri_process();

/*
우선 순위 작업 완료
1초 뒤에 프로세스1 완료
3초 뒤에 프로세스2 완료
6초 뒤에 프로세스3 완료
*/

 

setTimeout() 함수를 이용해 1,2,3초의 딜레이를 의도적으로 구현했습니다. pri_process()는 즉시 호출되고 process1,2,3번은 정해진 시간의 간격을 두고 실행이 됩니다. 실제로 걸리는 시간은 누적이 돼서 시간이 늘어납니다.

 

여기서 문제는 process를 등록하는 순서(방법)인데 함수 안에 함수 안에 함수입니다... 그럼 일단 ES6 스타일로 변신!

 

// ES6 스타일 방식
function process1(onFin){
  setTimeout(() => onFin('프로세스1 완료'), 1000);
}

function process2(onFin){
  setTimeout(() => onFin('프로세스2 완료'), 2000);
}

function process3(onFin){
  setTimeout(() => onFin('프로세스3 완료'), 3000);
}

function pri_process(){
  console.log('우선 순위 작업 완료');
}

process1(proc1 => {
  console.log('1초 뒤에', proc1);
  process2(proc2 => {
    console.log('3초 뒤에', proc2);
    process3(proc3 => {
      console.log('6초 뒤에', proc3);
    });
  });
});

pri_process();

 

ES6의 화살표 함수를 이용해 문법을 조금 변경했습니다. 그냥 function 키워드가 화살표식으로 바뀐 것뿐입니다.

여전히 계단식 함수function지옥 표현은 그대로입니다. 만약 이런 식으로 10개의 프로세스가 있다면... 더 이상 읍읍

 

그럼 이제 본론입니다. Promise 객체를 사용하면 훨씬 깔끔하고 유연한 코딩이 가능합니다. 요즘 것들은 거의 이런식

 

// Promise 객체 사용
const process1 = () =>
  new Promise(resolve => {
    setTimeout(() => resolve('프로세스1 완료'), 1000);
  });

const process2 = () =>
  new Promise(resolve => {
    setTimeout(() => resolve('프로세스2 완료'), 2000);
  });

const process3 = () =>
  new Promise(resolve => {
    setTimeout(() => resolve('프로세스3 완료'), 3000);
  });

function pri_process(){
  console.log('우선 순위 작업 완료');
}

const process_run = () => process1()
  .then(proc1 => {
    console.log(`1초 뒤에 ${proc1}`);
    return process2();
  });

process_run()
  .then(proc2 => {
    console.log(`3초 뒤에 ${proc2}`);
    return process3();
  })
  .then(proc3 => {
    console.log(`6초 뒤에 ${proc3}`);
  });
  
pri_process();

 

 뭔가 코드가 조금 길어진 것 같다는 생각은 기분 탓입니다! 사실 Promise 사용 시 기존 방식보다는 품이 좀 들지만 여러 변형된 방식으로 사용 가능합니다. 상기한 process_run() 함수를 보시면 process1을 실행하고 then() 메서드를 사용해 다음 프로세스를 기동하고 return 하면 또 Promise를 사용할 수 있기 때문에 연속적인 처리가 가능합니다.

 

하지만 과유불급이라 했던가요? 지나친 Promise 사용은 오히려 코드의 가독성을 떨어트릴 수 있으니 .then 지옥

적절한 사용과 코드의 분리가 필요합니다. 서버와의 데이터 요청에도 많이 사용되니 꼭 익혀두시길 바랍니다.

 

댓글