JS는 싱글스레드로 한 번에 하나의 작업만 할 수 있다. 이를 해결하기 위해서 비동기적 기법이 사용된다.
비동기적으로 처리하면 동시에 여러가지 작업을 처리 할 수 있는 방법있으며 기다기면서 다른 함수를 호출할 수 있다.
JS의 대표적인 비동기 처리 사례는 setTimeout()
을 쓰는 것이다.
일정 시간뒤에 함수를 실행시킨다.
console.log("시작")
setTimeout(function() {
console.log('5초 후 실행합니다.')
}, 5000)
console.log('끝')
// 시작
// 끝
// 5초 후 실행합니다.
위의 코드의 결과는 아래 주석과 같이 나온다.
다음과 같은 작업들은 주로 비동기적으로 처리하게 된다.
비동기 작업을 다룰 때에는 콜백 함수 외에도 Promise, 그리고 async/await 라는 문법을 사용하여 처리 할 수 있다.
이전에는 비동기 작업을 처리 할 때에는 콜백 함수로 처리를 해야 했었다. 콜백 함수로 처리를 하게 된다면 비동기 작업이 많아질 경우 코드가 쉽게 난잡해지게 되었다. 콜백 함수의 error, success의 처리를 보다 간단하게 하기 위해 Promise가 생겼다.
비동기적으로 처리해야 하는 일이 많아질수록, 코드의 깊이가 계속 깊어지는 현상이 있는데, Promise
를 사용하면 이렇게 코드의 깊이가 깊어지는 현상을 방지 할 수 있다.
Promise
는 주로 서버에서 받아온 데이터를 화면에 표시할 때 사용하게 된다. 일반적으로 웹 애플리케이션을 구현할 때 서버에서 데이터를 요청하고 받아온다. 서버에다가 ‘데이터 하나 보내주세요’ 라는 요청을 보내게 된다. 그런데 여기서 데이터를 받아오기도 전에 마치 데이터를 다 받아온 것 마냥 화면에 데이터를 표시하려고 하면 오류가 발생하거나 빈 화면이 뜹니다. 이와 같은 문제점을 해결하기 위한 방법 중 하나가 Promise
이다.
Promise
의 동작을 이해해보자. 먼저 아래 코드는 간단한 ajax 통신 코드이다.
function getData(callbackFunc) {
$.get('url 주소/products/1', function(response) {
callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
});
}
getData(function(tableData) {
console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
});
위 코드는 제이쿼리의 ajax 통신 API를 이용하여 지정된 url에서 1번 상품 데이터를 받아오는 코드이다. 비동기 처리를 위해 프로미스 대신에 콜백 함수를 사용했다.
위 코드에 Promise
를 적용하면 아래와 같아진다.
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를 사용한 구조로 바뀌었다.
Promise는 new Promise()로 생성할 수 있으며, 종료될 때 세 가지 상태를 갖게된다.
Promise는 resolve
와 reject
2개의 인자를 받으며, 비동기 처리가 성공하면 resolve
가 호출되고, 실패하면 reject
가 호출된다.
Promise의 특징 중 하나는 여러개의 Promise를 then()
을 이용해서 연결하여 사용할 수 있다는 점이다.
function getData() {
return new Promise({
// ...
});
}
// then() 으로 여러 개의 프로미스를 연결한 형식
getData()
.then(function(data) {
// ...
})
.then(function() {
// ...
})
.then(function() {
// ...
});
------------------------------------------
new Promise(function(resolve, reject){
setTimeout(function() {
resolve(1);
}, 2000);
})
.then(function(result) {
console.log(result); // 1
return result + 10;
})
.then(function(result) {
console.log(result); // 11
return result + 20;
})
.then(function(result) {
console.log(result); // 31
});
참조
velopert - Promise
Captain Pangyo - 자바스크립트 Promise 쉽게 이해하기
MJ KIM - 자바스크립트 비동기 함수 알아보기