동기:
비동기:
자바라스크립트 에서 비동기 작업을 하기 위해서 가장 흔히 사용하는것이 콜백(callback)함수이다.
//기본 콜백
function increase(number, callback) {
setTimeout(() => {
const result = number + 10;
if (callback) {
callback(result);
}
}, 1000);
}
//1초에 걸쳐서 걸쳐서 10,20,30,40 과 같은 형태로 여러번 순차적으로 처리하고 싶다면 콜백함수를 중첩하여 구현 할 수 있음
console.log("작업시작");
increase(0, (result) => {
console.log(result);
increase(result, (result) => {
console.log(result);
increase(result, (result) => {
console.log(result);
console.log("작업완료");
});
});
});
결과: 작업시작, 10,20,30,40 작업완료
이렇게 콜백안에 콜백을 넣어서 구현 할수는 있는데...여러번 중첩되어 가독성 이 떨어짐..그래서 callback hell (콜백지옥) 이라고 함.
Promise 는 콜백 지옥 같은 코드가 형성되지 않게 ES6에서 도입되었슴.
위 코드를 promise 로 바꿈
//Promise
function increase(number) {
const promise = new Promise((resolve, reject) => {
//resolve 성공 , reject(실패)
setTimeout(() => {
const result = number + 10
if (result > 50) {
//50보다 높으면 에러 발생시키기
const e = new Error("NumberTooBig")
return reject(e)
}
resolve(result) //number 값에 +10 후 성공 처리
}, 1000)
})
return promise
}
//Promise에서 resolve된 값은 .then을 통해 받아 올 수 있음
increase(0)
.then((number) => {
console.log(number)
return increase(number) //Promise 리턴하면
})
.then((number) => {
//또 then 처리 가능
console.log(number)
return increase(number)
})
.then((number) => {
console.log(number)
return increase(number)
})
.then((number) => {
console.log(number)
return increase(number)
})
.then((number) => {
console.log(number)
return increase(number)
})
.catch((e) => {
//도중에 에러가 발생한다면 .catch를 통해 알 수 있음
console.log(e)
})
여러 작업을 연달아 처리한다고 해서 함수를 여러번 감싸는 것이 아니라 .then 을 사용하여 그다음 작업을 설정하기 때문에 콜백 지옥이 형성되지 않음
async/await는 Promise 를 더욱 쉡게 사용 할 수 있도록 해주는 ES2017(ES8) 문법입니다.
이문법을 사용 하려면 함수의 앞부분에 async 키워드를 추가하고, 함수 내부에서 Promise 앞부분 await 키워드를 사용.
이렇게 하여 Promise 가 끝날때까지 기다리고, 결과 값을 특정 변수에 담을 수 있음.
//async/await
function increase(number) {
const promise = new Promise((resolve, reject) => {
//resolve 성공, reject는 실패
setTimeout(() => {
const result = number + 10
if (result < 50) {
//50보다 높으면 에러 발생시키기
const e = new Error("NumberTooBig")
return reject(e)
}
resolve(result) //number 값에 +10 후 성공 처리
}, 1000)
})
return promise
}
async function runTasks() {
//try catch 구문을 사용하여 에러를 처리
try {
let result = await increase(0)
console.log(result)
result = await increase(result)
console.log(result)
result = await increase(result)
console.log(result)
result = await increase(result)
console.log(result)
result = await increase(result)
console.log(result)
} catch (e) {
console.log(e)
}
}