1 = console.log(1) // 동기
3 = console.log(3) // 동기
Syschronous callback = printImmediately(print){print();} printImmediately(()=>{console.log('hello')})
// (동기적으로 실행하는 callback)
2 = setTimeout(()=>{console.log('2')},0) // 비동기
Asynchronous callback = printWithDelay(print, timeout)
{setTimeout(print,timeout)}printWithDelay(()=>{console.log('Asynchronous callback')},2000)
// (비동기적으로 실행하는 callback)
위처럼 출력된 것을 보아 동기들이 먼저 출력되고 그 후에 setTimeout이 들어간 비동기들이 출력되는것을 확인할 수 있다.
또 callback 중에서도 동기적으로 실행하는 Syschronous callback과 비동기적으로 실행하는 Asynchronous callback이 있음을 알 수 있다.
자바스크립트는 비동기 프로그램이라는 특성상 이벤트에 따라 받는 콜백이 복잡해지면 내부에서 지속적으로 콜백을 사용하게 되므로 코드 읽기가 아주 어려워지는 상황이 발생하게 된다. 이러한 상황을 콜백헬(Callback Hell) 이라고 한다.
정의
Javascript안에 내장되어 있는 비동기를 간편하게 처리할 수 있는 object
역할
callback을 위처럼 유용하게 쓰일때도 있지만 이렇게 callback을 계속해서 callback 안에 callback 함수를 부르고 부르다 보면 콜백지옥이 될 수 있기에 이를 보완하기 위해서 사용한다.
사용법 ( Promise의 3가지 상태(states) )
Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
new Promise((resolve,reject)=>{
// 빈값
});
Promise 메소드를 호출할 때 콜백함수를 선언할 수 있고 인자값은 resolve(성공시 반환)와 reject(실패시 반환)입니다.
Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
function prcatice(){
return new Promise((resolve,reject)=>{
let data = 100;
resolve(data);
});
}
prcatice().then((resolvedata)=>{
console.log(resolvedata)
})
콜백함수 resolve를 사용하여 이행상태로 만들고 .then을 사용하여 값을 전달받을 수 있습니다.
Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태
function prcatice(){
return new Promise(function(resolve,reject){
reject(new Error("OO 에러가 발생하였습니다"))
})
}
prcatice().then().catch(function(rejecterr){
console.log(rejecterr)
})
에러가 발생되면 catch로 무슨 에러가 발생했는지 확인할 수 있습니다.
const time = ()=>(parseInt(Math.random()*10)+1)*1000
const 아반떼 = cb => {
setTimeout(()=>{
console.log('아반떼 End')
cb()
}
,time())
console.log('아반떼 Go')
}
const 소나타 = cb => {
setTimeout(()=>{
console.log('소나타 End')
cb()
},time())
console.log('소나타 Go')
}
const 제네시스 = cb => {
setTimeout(()=>{
console.log('제네시스 End')
cb()
}
,time())
console.log('제네시스 Go')
}
console.log("경기시작")
아반떼(()=>{
소나타(()=>{
제네시스(()=>{
console.log("경기 종료")
})
})
})
const time = ()=>(parseInt(Math.random()*10)+1)*1000
const 아반떼 = () => {
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("아반떼 End")
},time())
console.log('아반떼 Go')
})
}
const 소나타 = () => {
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("소나타 End")
},time())
console.log('소나타 Go')
})
}
const 제네시스 = () => {
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("제네시스 End")
},time())
console.log('제네시스 Go')
})
}
console.log('경기 시작')
아반떼()
.then(data=>{
console.log(data)
return 소나타()
})
.then(data=>{
console.log(data)
return 제네시스()
})
.then(data=>{
console.log(data)
console.log('경기 종료')
})
코드가 많아 질수록 callback을 많이 사용하여 코드가 > 이런식으로 밀리게 되어 코드를 읽기 어려워지지만 Promise 객체를 사용하여 이를 방지하였다. (코드가 길어진다면 더 효과가 좋을거같다.)
정의
Javascript의 비동기를 처리하는 비교적 최근에 나온 문법
역할
Promise를 조금 더 간결하고 간편하고 동기적으로 실행되는것처럼 보이게 해준다.
사용예시
const time = ()=>(parseInt(Math.random()*10)+1)*1000
const 아반떼 = () => {
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("아반떼 End")
},time())
console.log('아반떼 Go')
})
}
const 소나타 = () => {
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("소나타 End")
},time())
console.log('소나타 Go')
})
}
const 제네시스 = () => {
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("제네시스 End")
},time())
console.log('제네시스 Go')
})
}
async function init(){
console.log('경기 시작')
let a = await 아반떼()
console.log(a)
let b = await 소나타()
console.log(b)
let c = await 제네시스()
console.log(c)
console.log('경기 종료')
}
init()
함수 앞에 async를 사용하여 자동으로 Promise로 바꿔주고 await은 async가 붙은 함수 안에서만 사용할 수 있고 promise객체의 딜레이가 끝날때까지 기다려준 후 실행한다.
promise를 사용했을때 .then으로 값을 가져오는것 보다 보기 편한것 같다.