📌 참고 사이트
자바스크립트 Promise 쉽게 이해하기 • 캡틴판교 (joshua1988.github.io)
자바스크립트 Promise 쉽게 이해하기
(중급) 자바스크립트 입문자를 위한 Promise 설명. 쉽게 알아보는 자바스크립트 Promise 개념, 사용법, 예제 코드. 예제로 알아보는 then(), catch() 활용법
joshua1988.github.io
📋 Promise란?
자바스크립트에서 비동기 처리를 위한 객체이다.
프로미스는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과값을 나타낸다.
❓ 비동기
특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 자바스크립트의 특성을 말한다.
📍 Promise가 필요한 이유
프로미스는 서버에서 받아온 데이터를 화면에 표시할 때 많이 사용한다.
서버에 데이터를 요청하였는데 데이터를 전부 받아오기도 전에 마치 데이터를 다 받아온 것처럼 화면에 렌더링 하려 하면 오류가 발생하거나 빈 화면이 뜨게 된다.
이러한 문제를 프로미스를 통해 해결할 수 있다.
📋 프로미스 기본 코드
ajax 통신 코드를 만들 때 프로미스를 사용할 수 있다.
❓ ajax
Asynchronous Javascrpit And Xml의 약자로, 자바스크립트를 이용해 서버와 브라우저가 비동기적으로 데이터를 교환할 수 있는 통신 기능이다.
브라우저가 가지고 있는 XMLHttpRequest 객체를 이용해 전체 페이지를 새로 고치지 않고도 페이지의 일부만을 위한 데이터를 로드하는 기법이다.
JSON이나 XML 형태로 필요한 데이터만 받아 갱신하므로 그만큼의 시간과 자원을 아낄 수 있다.
AJAX란 무엇인가?
AJAX (Asynchronous Javascript And XML) AJAX란, JavaScript의 라이브러리중 하나이며 Asynchronous Javascript And Xml(비동기식 자바스크립트와 xml)의 약자이다. 브라우저가 가지고있는 XMLHttpRequ
velog.io
💻 ajax 통신 코드 작성하기
다음은 간단한 ajax 통신 코드의 형태이다.
function getData(callbackFunc) {
// 서버에 데이터 요청
$.get('url 주소/products/1', function(response) {
// 서버에서 받은 데이터인 response를 callbackFunc에 넘겨준다.
callbackFunc(response);
});
}
// getData의 인자로 함수 전달
getData(function(tableData) {
// $.get()의 response 값이 tableData에 전달되어 console에 출력된다.
console.log(tableData);
});
위 코드는 제이쿼리의 ajax 통신 API를 이용해 지정된 url에서 1번 상품 데이터를 받아오는 코드이다.
위 코드에 프로미스를 적용하여 작성한다면 다음과 같이 된다.
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()의 결과값이 여기로 전달됨 ($.get()의 response값이 tableData에 전달됨)
console.log(tableData);
});
📋 프로미스의 3가지 상태 (states)
프로미스의 상태는 프로미스의 처리 과정을 의미한다.
new Promise()로 프로미스를 생성하고 종료될 때까지 다음과 같은 3가지 상태를 갖는다.
➡️ Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
➡️ Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
➡️ Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태
📍 Pending (대기)
아래와 같이 new Promise() 메서드를 호출하면 대기 상태가 된다.
new Promise();
new Promise() 메서드를 호출할 때 콜백 함수를 선언할 수 있고, 콜백 함수의 인자는 resolve, reject이다.
new Promise(function(resolve, reject) {
// resolve 또는 reject 관련 코드 작성
});
📍 Fulfilled (이행)
new Promise에 넘겨준 콜백 함수의 인자 resolve를 실행시키면 이행 (완료) 상태가 된다.
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에 넘겨준 콜백 함수의 인자 reject를 실행시키면 실패 상태가 된다.
new Promise(funciton(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);
});
❓ 프로미스는 비동기?
프로미스 자체가 비동기인 것이 아니라 프로미스는 비동기 작업을 어떠한 방식으로 처리할 것인지에 대한 것을 구현해 놓은 것이라고 생각해야 한다.
처음에는 '서버에 응답을 요청하고, 응답의 결과에 따라서 resolve 함수 또는 reject 함수 호출이 결정되고, resolve 함수가 호출되면 then 안의 콜백 함수가 실행되고, reject 함수가 호출되면 catch 안의 콜백 함수가 실행되는 과정을 거치는 과정을 보면 순차적으로 한 작업이 끝나고 결과가 나와야 다른 작업이 이루어질 수 있는 동기적 작동 방식을 가지고 있는데 어떻게 프로미스가 비동기인거지?' 라고 프로미스의 정의에서 좀 벗어난 생각을 하였다.
비동기 작업의 처리를 위하여 콜백을 사용하면 함수가 계속 중첩되는 콜백 지옥에 빠질 수 있고, 오류 처리가 어려워진다. 이때 프로미스를 사용하여 비동기 작업에 대한 순차적 처리를 위와 같은 단점을 보완하면서 처리할 수 있다.
프로미스의 핵심은 복잡하게 생각하기보다 사용하는 목적을 이해하는 것이다.
비동기 작업 처리 시 비동기 작업의 성공과 실패의 경우를 분리하여 메서드를 수행하는 것이라고 생각하자.
프로미스 실행 후 나온 결과값을 메서드를 통해 나중에 처리하는 것이다.
* 다음과 같은 코드에서 실행 결과가 1 2 3 이 아닌 1 3 2가 되는 것은 then 메서드와 catch 메서드에 인자로 들어가는 콜백 함수가 비동기적으로 실행되기 때문이다. (이는 마이크로 태스크 큐와 관련이 있다.)
console.log(1)
function promise1() {
return new Promise((resolve) => {
resolve(2);
});
}
promise1().then((num) => console.log(num));
console.log(3);
ES6 프로미스(Promise), 진짜 쉽게 이해하기 (Promise의 목적만 생각한다.) (tistory.com)
ES6 프로미스(Promise), 진짜 쉽게 이해하기 (Promise의 목적만 생각한다.)
프로미스(Promise) 싱글쓰레드인 자바스크립트에서 비동기 처리를 위해서 콜백(callback)을 사용해왔다.덕분에 비동기 처리를 온전히 해낼 수 있었지만 이런 콜백이 사용되는 경우가 많아지면서 단
jeong-pro.tistory.com
📋 프로미스 사용 예제
function getData() {
return new Promise(function(resolve, reject) {
// 지정된 url에서 1번 상품 데이터를 가져오기
// 응답은 콜백 함수의 response에 인자로 들어감.
$.get('url 주소/products/1', function(response) {
// 응답이 있을 경우
if (response) {
// resolve 메서드 호출 (인자로 응답을 보냄)
resolve(response);
}
// 응답이 없으면 reject 메서드 호출 (에러 객체를 생성해 에러 메시지를 넣어줌)
reject(new Error('Request is failed'));
});
});
}
// getData 실행 결과 resolve 메서드가 실행되어 이행 상태가 되면 then 안의 코드 실행
getData().then(function(data) {
// 받아온 response는 data로 들어가고, 그것을 그대로 console에 출력
console.log(data);
// reject 메서드가 실행되어 실패 상태가 되면 받아온 에러 객체가 err로 들어가고, 그것을 그대로 console에 출력
}).catch(function(err) {
console.error(err);
});
📋 여러 개의 프로미스 연결하기 (Promise Chaining)
프로미스는 여러 개의 프로미스를 연결하여 사용할 수 있다는 특징이 있다.
앞에서 보았던 then 메서드를 호출하고 나면 새로운 프로미스 객체가 반환된다.
💻 setTimeout() API를 이용한 프로미스 체이닝 예시
new Promise(function(resolve, reject) {
// 2초 후에 resolve 함수 호출 (1 전달)
setTimeout(function() {
// resolve가 호출되면 프로미스가 대기 상태에서 이행 상태로 넘어감.
resolve(1);
}, 2000);
})
.then(function(result) {
console.log(result); // 1 (2초 후에 출력)
return result + 10; // 1 + 10의 결과를 다음 then으로 넘김
})
.then(function(result) {
console.log(result); // 11
return result + 20; // 11 + 20의 결과를 다음 then으로 넘김
})
.then(function(result) {
console.log(result); // 31
});
📋 실무에서 있을 법한 프로미스 연결 사례
사용자 로그인 인증 로직에 프로미스 체이닝을 사용하여 코드를 작성해 볼 수 있다.
getData(userInfo)
.then(parseValue)
.then(auth)
.then(display);
// 사용자 정보가 담긴 객체
var userInfo = {
id: 'test@abc.com',
pw: '****'
}
// 여기서부터는 프로미스를 반환해 주는 함수
// 각 함수가 반환하는 프로미스 내부에서 작업이 성공하면 연결된 then 메서드 안의 콜백 함수가 실행됨.
// 입력된 사용자 정보를 파싱
function parseValue() {
return new Promise((resolve, reject) => {
// ... 작업 수행 ...
if (작업 성공 조건) {
resolve(결과값);
} else {
reject(에러);
}
});
}
// 사용자 정보 인증
function auth() {
return new Promise((resolve, reject) => {
// ... 작업 수행 ...
if (작업 성공 조건) {
resolve(결과값);
} else {
reject(에러);
}
});
}
// 사용자 정보 보여주기
function display() {
return new Promise((resolve, reject) => {
// ... 작업 수행 ...
if (작업 성공 조건) {
resolve(결과값);
} else {
reject(에러);
}
});
}
'Javascript study' 카테고리의 다른 글
[JS] async와 await (0) | 2023.09.04 |
---|---|
[JS] fetch (0) | 2023.09.03 |
[JS] IndexedDB (2) | 2023.08.27 |
[JS] Closure (0) | 2023.08.27 |
[JS] 실행 컨텍스트 (2) (0) | 2023.08.25 |
댓글