? Promise가 뭔가요?
프로미스는 자바스크립트 비동기 처리에 사용되는 객체입니다.
? Promise가 왜 필요한가요?
데이터를 받아오기도 전에 마치 데이터를 다 받아온 것 마냥 화면에 데이터를 표시하려고 하면 오류가 발생하거나 빈 화면이 뜹니다. 이와 같은 문제점을 해결하기 위한 방법 중 하나가 프로미스입니다.
비동기 처리? 그게 뭔가요?
자바스크립트의 비동기 처리란 특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 자바스크립트의 특성을 의미합니다.
만약, 복잡한 코드가 있으면 이 코드를 실행하는 50초 동안은 아무 것도 할 수 없습니다. 50초 후에야 다음 행동이 실행될 겁니다. 사용자들은 멍하니 기다리거나 화가 나서 앱을 종료할 겁니다.
$.Deferred
이럴때 비동기 프로그래밍이 필요합니다. 흔히 콜백 형식이나 프로미스 형식을 사용하는 데, 콜백 형식은 점점 더 코드가 복잡해지는 문제를 발생시키기 때문에, 콜백이 여러 번 중첩될 것 같으면 프로미스 형식을 사용해야합니다.
var longAndComplicatedFunction = function() {
var deferred = $.Deferred();
try {
// 완료되려면 50초가 걸리는 매우 복잡한 비동기 코드
deferred.resolve('성공');
} catch (err) {
deferred.reject(err);
}
return deferred.promise();
};
longAndComplicatedFunction().done(function(message) {
console.log(message);
}).fail(function(error) {
console.log(error);
}).always(function() {
console.log('완료!');
});
console.log('다음 행동');
-> 성공했을 때에는 resolve, 실패했을 때에는 reject 메소드를 호출하면 resolve는 done으로, reject는 fail로 연결됩니다.
이제 비동기 방식으로 했기 때문에 다음 행동은 50초를 기다릴 필요 없이 바로 실행되고, 복잡한 행동이 완료되었을 시 등록해둔 done 메소드가 실행됩니다. 실패했다면 fail 메소드가 실행되고요.
콜백 함수를 쓸 수도 있지만, 콜백 함수는 문제가 있을 수 있다. 아래 참조.
콜백 함수로 비동기 처리 방식의 문제점 해결하기
앞에서 자바스크립트 비동기 처리 방식에 의해 야기될 수 있는 문제들을 살펴봤습니다. 이러한 문제들은 어떻게 해결할 수 있을까요? 바로 콜백(callback) 함수를 이용하는 것입니다. 앞에서 살펴본 ajax 통신 코드를 콜백 함수로 개선해보겠습니다.
[콜백 함수 코드 01]
function getData(callbackFunc) {
$.get('https://domain.com/products/1', function(response) {
callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
});
}
getData(function(tableData) {
console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
});
이렇게 콜백 함수를 사용하면 특정 로직이 끝났을 때 원하는 동작을 실행시킬 수 있습니다.
콜백 함수의 동작 방식은 일종의 식당 자리 예약과 같습니다.
콜백 지옥 (Callback hell)
콜백 지옥은 비동기 처리 로직을 위해 콜백 함수를 연속해서 사용할 때 발생하는 문제입니다. 아마 아래와 같은 코드를 본 적이 있을 겁니다.
$.get('url', function(response) {
parseValue(response, function(id) {
auth(id, function(result) {
display(result, function(text) {
console.log(text);
});
});
});
});
위와 같이 콜백 안에 콜백을 계속 무는 형식으로 코딩을 하게 됩니다. 이러한 코드 구조는 가독성도 떨어지고 로직을 변경하기도 어렵습니다. 이와 같은 코드 구조를 콜백 지옥이라고 합니다.
- > 콜백 지옥을 해결하는 방법에는 Promise나 Async를 사용하는 방법이 있습니다. 만약 코딩 패턴으로만 콜백 지옥을 해결하려면 아래와 같이 각 콜백 함수를 분리해주면 됩니다.
[콜백 함수 코드 01] 에 프로미스를 적용 시키면 아래와 같다
function getData(callback) {
// new Promise() 추가
return new Promise(function(resolve, reject) {
$.get('url 주소/products/1', function(response) {
// 데이터를 받으면 resolve() 호출
resolve(response);
});
});
}
// getData()의 실행이 끝나면 호출되는 then()
getData().then(function(tableData) {
// resolve()의 결과 값이 여기로 전달됨
console.log(tableData); // $.get()의 reponse 값이 tableData에 전달됨
});
콜백 함수로 처리하던 구조에서 new Promise(), resolve(), then()와 같은 프로미스 API를 사용한 구조로 바뀌었습니다. 여기서 new Promise()는 좀 이해가 가겠는데 resolve(), then()은 뭐 하는 애들일까요? 아래에서 함께 알아보겠습니다.
프로미스의 3가지 상태(states)
new Promise()로 프로미스를 생성하고 종료될 때까지 3가지 상태를 갖습니다.
- Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
- Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
- Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태
Pending(대기)
먼저 아래와 같이 new Promise() 메서드를 호출하면 대기(Pending) 상태가 됩니다.
new Promise ();();()()
new Promise() 메서드를 호출할 때 콜백 함수를 선언할 수 있고, 콜백 함수의 인자는 resolve, reject입니다.
new Promise((function((resolve, reject ));) { // ...
Fulfilled(이행)
여기서 콜백 함수의 인자 resolve를 아래와 같이 실행하면 이행(Fulfilled) 상태가 됩니다.
new Promise(function(resolve, reject) {
resolve();
});
그리고 이행 상태가 되면 아래와 같이 then()을 이용하여 처리 결과 값을 받을 수 있습니다.
function getData() {
return new Promise(function(resolve, reject) {
var data = 100;
resolve(data);
});
}
// resolve()의 결과 값 data를 resolvedData로 받음
getData().then(function(resolvedData) {
console.log(resolvedData); // 100
});
});
Rejected(실패)
new Promise()로 프로미스 객체를 생성하면 콜백 함수 인자로 resolve와 reject를 사용할 수 있다고 했습니다. 여기서 reject를 아래와 같이 호출하면 실패(Rejected) 상태가 됩니다.
new Promise(function(resolve, reject) {
reject();
});
그리고, 실패 상태가 되면 실패한 이유(실패 처리의 결과 값)를 catch()로 받을 수 있습니다.
function getData() {
return new Promise(function(resolve, reject) {
reject(new Error("Request is failed"));
});
}
// reject()의 결과 값 Error를 err에 받음
getData().then().catch(function(err) {
console.log(err); // Error: Request is failed
});
);
출처 : https://www.zerocho.com/category/jQuery/post/57c90814addc111500d85a19
'WEB Front-End > JQuery' 카테고리의 다른 글
JQuery 학습 04 - getJSON 를 이용한 json 데이터 접근 (0) | 2021.09.14 |
---|---|
JQuery 학습 03 - ajax 를 이용한 XML 데이터 접근 (0) | 2021.09.14 |
JQuery 학습 02 - Dom 조작, Dom 이동, 배열, 필터 (0) | 2021.09.10 |
JQuery 학습 01 - 액션, Math, 이벤트 (0) | 2021.09.10 |