롸?
[ES6] 비동기 자바스크립트 Promise 본문
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에 모든 유저의 정보를 요청한 뒤, 그대로 출력하는 간단한 예시이다.
- myCallBack 이라는 함수를 작성해서 DB.getAllUsers()의 인자로 전달.
- 실패할 경우에 대비해서 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()을 처리한다.
- getAllUser 라는 함수는 callback_function이라는 인자를 받아서,
- 유저가 없으면 callback_function(에러, undefined)
- 유저가 있으면 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);
});
참고
2. https://peter-cho.gitbook.io/book/10/promise
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 |