오늘은 어렵고 어려운 비동기에 대해서 알아본다!🐹
요청을 보내고 결과를 받을 때까지 다음 요청을 대기한다. 요청을 순차적으로 처리한다.
console.log('a');
console.log('b');
console.log('c');
//a
//b
//c
비동기는 동기와 다르게 요청이 끝나지 않아도 다음 요청을 실행하는 것이다.
데이터를 서버에 요청하면 서버는 데이터를 전달하고 해당 데이터를 클라이언트에 뿌려야 한다. 비동기적으로 서버에 데이터를 요청해야 한다. 동기로 요청하게 된다면 앱 실행이 끝나고 서버에 요청이 되므로 서버에 부담이 갈 것이고 또한, 클라이언트는 데이터를 기다려야 한다.
console.log('a');
setTimeout(()=>{
console.log('b')
},100);
console.log('c')
//a
//c
//b
비동기는 멀티 스레드가 지원되어야 한다. 하지만 Javascript 는 싱글 스레드이다.
자바스크립트는 웹 브라우저, node.js의 자바스크립트 엔진에서 실행된다. 엔진에는 자바스크립트를 돌리는 싱글 스레드가 있다. 비동기식 처리 모델인 Web API 라는 것이 함께 동닥한다. 여기서 setTimeout이나 AJAX로 http 데이터를 가져오는 일을 처리한다.
Web API들이 자바스크립트 엔진 스레드와 다르게 비동기 처리를 따로 돈다. Callback함수를 가지고 이벤트 loop에 들어가 처리되는 대로 callback함수를 자바스크립트 엔진으로 보낸다.
Callback 함수는 특정 함수에 매개 변수로 전달된 함수를 의미한다.
요청이 실행되고 끝날 때까지 기다리는 것이 아니라 다른 작업을 하다가 데이터가 준비가 되었을 때 콜백 함수를 실행하게 된다.
function Callback(callback){
console.log("call back function")
callback()
}
Callback(function(){
console.log('콜백 받는 곳')
}
콜백 지옥은 비동기 처리 로직을 위해 콜백 함수를 연속해서 사용할 때 발생한다.
모든 과정을 비동기로 처리할 떼 콜백 함수가 꼬리에 꼬리를 무는 콜백지옥이 나타난다.
function Callback1(callback){
function Callback2(callback){
function Callback3(callback){
console.log('callback hell')
}
}
}
일반적으로 ES7,8 의 promise나 async await 를 사용하면 된다.
콜백 함수로 해결하려면 각 콜백 함수를 분리하면 된다.
function Callback3Done(callback){
console.log('callback')
}
function Callback2Done(callback){
Callback3(callback,Callback3Done)
}
function Callback1(callback){
Callback2(callback,Callback2Done)
}
Promise는 자바스크립트 비동기 처리에 사용되는 객체이다.
주로 서버에서 받아온 데이터를 화면에 표시할 때 사용된다. 데이터를 받고 표시하도록 한다.
간단한 AJAX 통신 코드를 보면,
function getData(callbackFunc){
$.get('url 주소/products/1', function(response) {
callbackFunc(response);
});
getData(function(tableData){
console.log(tabelData)
});
Promise를 적용하면,
function getData(callback){
return new Promise(function(resolve,reject){
$.get('url 주소/products/1', function(response) {
resolve(response);
});
});
}
getData()
.then(function(tableData){ });
전체 예제
function getData(){
return new Promise(function(resolve,reject){
$.get('url',function(res){
if(res) resolve(res);
else reject(new Error("request error!"));
});
});
}
getData()
.then(function(data){
console.log("success")
})
.catch(function(err){
console.log(err)
})
new Promise(function(resolve,reject){});
callback 함수의 인자는 resolve, reject가 있다.
new Promise(function(resolve, reject) {
resolve();
});
Fulfilled 상태가 되면 then()을 이용해서 처리 값을 받아온다.
function getData(){
return new Promise(function(resolve,reject){
let data = 100
resolve(data)
})
}
getData()
.then(res=>{
console.log(res)
})
new Promise(function(resolve, reject) {
reject();
});
Rejected 상태는 catch() 로 처리할 수 있다.
function getData(){
return new Promise(function(resolve,reject){
reject(new Error("reject");
})
}
getData()
.catch(err=>console.log(err))
프로미스의 특징은 연결을 지을 수 있다는 것이다.
then()을 호출하면 반환값으로 프로미스 객체가 반환된다.
function getData(){
return new Promise()
}
getData()
.then(function(data){})
.then(function(){})
.then(function(){})
fetch(url)
.then(process)
.then(save)
.catch(handleErrors)
;
save.then(
handleSuccess,
handleError
)
이 경우는 에러를 완벽하게 잡아내지 못한다.
프로미스에서 resolve로 완벽하게 수행해도
then의 첫번째 인자에서 에러가 발생하면 그 에러를 catch할 수 없기 때문이다.
2. catch()
save().then().catch()
프로미스 에러 핸들링의 권장하는 방법이다.
가장 최근에 나온 비동기 처리 문법이다. 프로미스를 보완하여 가독성 좋은 코드로 만들어준다.
기본 코드
function getData(){
let data = fetch(url)
if(data)
console.log(data)
}
자바스크립트 콜백 사용
function getData(){
let data = fetch(url,function(data){
if(data) {
console.log(data) }
})
}
async await 사용
async function getData(){
let data = await fetch(url)
if(data)
console.log(data)
}
전체 코드 예제
function fetchData(){
return new Promise( function(resolve,reject){
let data = 100;
resolve(data);
});
}
async function getData(){
let resultData = await fetchData()
}
async function 함수명(){
await 비동기 메서드()
}
함수 앞에 async 키워드를 붙여준다. 그리고 데이터를 fetch해오는 곳에 await 키워드를 붙여준다. 주의할 것은 비동기 처리 메서드가 꼭 프로미스로 반환되어야 한다는 것이다.
try catch 를 이용하면 된다.
async function getData(){
try{
let data = await fetchData()
if(fetchData)
let user = await fetchUser()
}catch(err){
console.log(err)
}
}
자바스크립트 비동기 처리와 콜백 함수
자바스크립트 Promise 쉽게 이해하기
자바스크립트 async와 await