롸?

[ES6] 비동기 자바스크립트 Promise 본문

WEB/JavaScript & jQuery

[ES6] 비동기 자바스크립트 Promise

허니버터새우깡 2022. 2. 7. 18:17

ES6부터 지원되는 Promise 객체를 통해 비동기 처리식을 사용할 수 있다.

 

 

1. 콜백함수(왜 프로미스를 쓰는가?)

콜백함수(Callback Function)란 파라미터로 함수를 전달받아, 함수의 내부에서 실행하는 함수이다. 콜백함수는 함수의 내부에서 실행되기 때문에 익명의 함수를 사용한다. 

ex) forEach 안에 익명의 함수를 넣어서 forEach 문을 동작시킨다.

let number = [1, 2, 3];

number.forEach(x => {
        console.log(x * 2);
});

//<output>
//2
//4
//6

비동기 호출이 자주 일어나는 프로그램의 경우 ‘콜백 지옥’이 발생한다.
함수의 매개변수로 넘겨지는 콜백 함수가 반복되어 코드의 들여쓰기 수준이 감당하기 힘들어질 정도로 깊어지는 현상이다. 


2. 콜백 함수로 비동시 처리하는 방식

// App.js
import DB from ‘./DB.js’

DB.getAllUser( function myCallBack(error, users) {
if(error) {
console.log(‘에러발생’);
console.log(error);
return;
    }
    console.log(‘성공’);
    console.log(users);
})

DB에 모든 유저의 정보를 요청한 뒤, 그대로 출력하는 간단한 예시이다.

  1. myCallBack 이라는 함수를 작성해서 DB.getAllUsers()의 인자로 전달.
  2. 실패할 경우에 대비해서 myCallBack 함수의 인자로 error도 받는다.
// DB.js
const user_list = [‘sam’, ‘tom’];

function getAllUser(callback_function) {
if(user_list.length === 0) {
callback_function(new Error(‘없다!’), undefined); 
return;
    }
    callback_function(undefined, user_list);
}

DB에서는 다음과 같이 myCallBack()을 처리한다.

  1. getAllUser 라는 함수는 callback_function이라는 인자를 받아서,
  2. 유저가 없으면 callback_function(에러, undefined)
  3. 유저가 있으면 callback_function(undefined, 유저목록) 형태로 실행한다.

첫번째에는 에러, 두번째에는 유저목록을 넣어서 실행하는 것은 하나의 약속이다.
이 약속만 지킨다면 누구든지 function myCallBack(error, users) {} 형태로 콜백함수를 작성하여 DB.js에 비동기 작업을 요청할 수 있다.

 

3. 비동기 콜백을 Promise로 바꿔보기

Promise는 이런 식으로 작성될 수 있다.

new Promise((resolve, reject) => {
if(조건) {
resolve(‘성공’);
}
    reject(‘실패’);
})


위의 DB.js를 콜백방식에서 프로미스 방식으로 바꾸어보자.

// DB.js
const user_list = [‘sam’, ‘tom’]

function getAllUsers () {
return new Promise((resolve, reject) => {
if(user_list.length === 0) {
    // 실패
    Reject(new Error(‘없다!!’))
} else {
    // 성공
    Resolve(user_list)
}
     })
}

콜백 방식은 성공 / 실패 를 구분하는 방법은 콜백함수의 인자 위치(순서) 이고
프로미스 방식은 성공 / 실패resolve / reject호출로 구분된다.

 


4. Promise 상태

Promise의 상태는 대기, 이행, 거부 상태가 있다. 상태는 대기에서 이행 / 거부 로만 변경이 가능하다.

  • 대기 : 초기상태
  • 이행 : 성공상태, resolve(), Promise.resolve()
  • 거부 : 실패상태, reject(), Promise.reject()

이행상태는 then으로 처리할 수 있다. Resolve()를 통해 전달한 값이 then에 인자로 전달된다.

Promise.resolve(10)
    .then(result => console.log(result)

//<output>
//10


거부상태는 catch으로 처리할 수 있다. Reject()를 통해 전달한 값이 catch에 인자로 전달된다.

Promise.reject({code: 404})
    .catch( ({code}) => console.log(code))

//<output>
//404

 

5. 응답 결과 전달 방법

응답 결과의 전달에 있어서 callback과 Promise 차이가 있다.


프로미스는 then을 호출해야 결과를 얻는다. 

let result;
const promise = new Promise(r => $.post(url1, data1, r));
promise.then(v => {
    result = v;
});

필요할 때 then을 호출해서 데이터를 받는 것이다.

const promise1 = new Promise(r => $.post(url1, data1, r));
const promise2 = new Promise(r => $.post(url2, data2, r));
promise1.then(result => {
    promise2.then(v => {
        result.nick = v.nick;
        report(result);
    });
});


콜백은 보낼 수는 있지만 언제 올지는 모른다.

$.post(url. data, () => {
  // 언제 실행 되는 가
})

현실적으로 다수의 API 요청을 통해 결과를 만들기 때문에 언제 응답이 오는지 중요하다. 

let result;
$.post(url1, data1, v => {
    result = v;
});
$.post(url2, data2, v => {
    result.nick = v.nick;
    report(result);
});




참고 

1.  https://velog.io/@rejoelve/%EB%B4%90%EB%8F%84-%EB%B4%90%EB%8F%84-%ED%97%B7%EA%B0%88%EB%A6%AC%EB%8A%94-resolve-reject

2.  https://peter-cho.gitbook.io/book/10/promise

3. https://velog.io/@minidoo/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%BD%9C%EB%B0%B1-%ED%95%A8%EC%88%98Callback-Function

4.  https://blog.naver.com/sssang97/221641377051

5. https://joshua1988.github.io/web-development/javascript/promise-for-beginners/ 

6.  

'WEB > JavaScript & jQuery' 카테고리의 다른 글

[ES6] Spread Operator (스프레드 연산자)  (0) 2022.02.07
자바스크립트 화살표 함수  (0) 2020.03.12
jQuery  (0) 2020.03.12
자바스크립트 이벤트 핸들링  (0) 2020.03.11
자바스크립트 스코프 호이스팅  (0) 2020.03.10
Comments