비동기 - 콜백과 프로미스 객체의 이해
function a() {
console.log('A')
}
function b() {
console.log('B')
}
a()
b()
위처럼 코드 작성 순서대로 출력된 방식이 동기 방식(Synchronous)라고 부릅니다.
function a() {
setTimeout( () => {
console.log('A')
}, 1000)
}
function b() {
console.log('B')
}
a()
b()
위처럼 a함수에 setTimeout함수를 사용해, 결국 B를 먼저 출력하고 A가 출력됩니다.
function a(callback) {
setTimeout( () => {
console.log('A')
callback()
}, 1000)
}
function b() {
console.log('B')
}
a(function() {
b()
})
함수와 상관없이 무조건 먼저 작성한 a함수를 실행한 후 b함수를 실행을 보장해줄 수 있는 콜백을 사용할 수 있습니다.
a함수에 setTimeout을 사용해도 불구하고 먼저 A를 출력한 후 callback()을 실행해 B를 출력합니다.
어떤 함수의 로직이 끝나고 다음 함수 실행을 callback함수로 보장했습니다.
function a(callback) {
setTimeout( () => {
console.log('A')
callback()
}, 1000)
}
function b(callback) {
setTimeout( () => {
console.log('B')
callback()
}, 1000)
}
function c(callback) {
setTimeout( () => {
console.log('C')
callback()
}, 1000)
}
a(function() {
b(function() {
c(function() {
console.log('Done!')
})
})
})
위에 예시 보시면 콜백함수들이 너무 많으면 a, b, c함수 실행 시 점점 파고 들어가는 구조가 콜백지옥입니다.
지금은 3개만 있어서 잘 구분할 수 있지만 많아지면 이런 방식으로 관리하기 매우 불편할 수 있습니다.
이럴 때는 promise 객체를 사용할 수 있습니다.
function a() {
// promise: 약속의 객체
return new Promise(function (resolve) {
setTimeout(() => {
console.log('A')
resolve()
}, 1000)
})
}
function b() {
console.log('B')
}
async function test() {
await a()
b()
}
test()
위에는 promise객체를 사용한 예시입니다.
a함수가 실행되면 같은 로직을 Promise 객체에 담고 반환됩니다.
async과 await 키워드를 사용해서 a함수가 실행 끝나고 b함수를 실행할 수 있습니다.
function a() {
return new Promise(function (resolve) {
setTimeout(() => {
console.log('A')
}, 1000)
})
}
function b() {
return new Promise(function (resolve) {
setTimeout(() => {
console.log('B')
}, 1000)
})
}
function c() {
return new Promise(function (resolve) {
setTimeout(() => {
console.log('C')
}, 1000)
})
}
async function test() {
await a()
await b()
await c()
console.log('Done!')
}
test()
방금 콜백지옥을 위에 async, await를 통해 관리하기 편한 방식으로 동작할 수 있습니다.
비동기 - 예외 처리(then, catch, finally)
promise 객체는 ES6에서 나오는 개념이지만, async과 await는 ES8에서 나왔습니다.
async과 await로 처리할 수 없을 때는 예외 처리를 통해 작동해야 됩니다.
function a() {
return new Promise(function (resolve) {
setTimeout(() => {
console.log('A')
}, 1000)
})
}
function test() {
// const promise = a()
// promise.then(() => {
// console.log('B')
// })
a().then(() => {
console.log('B')
})
}
test()
a함수를 promise변수에 담고, promise.then()메소드를 통해 다음을 실행해줍니다.
a가 실행하는 곳에서 promise변수가 반환됨으로 굳이 promise변수 사용 안 해도 됩니다.
a().then()로 바로 표현해도 됩니다.
function a() {
return new Promise(function (resolve) {
setTimeout(() => {
console.log('A')
}, 1000)
})
}
function b() {
return new Promise(function (resolve) {
setTimeout(() => {
console.log('B')
}, 1000)
})
}
function c() {
return new Promise(function (resolve) {
setTimeout(() => {
console.log('C')
}, 1000)
})
}
function test() {
a().then(() => {
return b()
}).then(() => {
return c()
}).then(() => {
console.log('Done!')
})
test()
}
여러개의 콜백을 사용하면 위에 체이닝방식으로 작성하면 됩니다.
function a(number) {
return new Promise(function (resolve, reject) {
if (number > 5) {
reject()
return
}
setTimeout(() => {
console.log('A')
}, 1000)
})
}
function test() {
a(7)
.then(() => {
console.log('Resolve!')
})
.catch(() => {
console.log('Reject!')
})
}
test()
위처럼 a함수에 number변수를 들어갈 때 조건문을 실행됩니다.
5보다 크면 reject합니다.
then()는 함수가 잘 처리 됐을 때 실행된 내용, catch()는 함수가 거부했을 때 처리된 내용을 출력합니다.
function a(number) {
return new Promise(function (resolve, reject) {
if (number > 5) {
reject()
return
}
setTimeout(() => {
console.log('A')
}, 1000)
})
}
function test() {
a(7)
.then(() => {
console.log('Resolve!')
})
.catch(() => {
console.log('Reject!')
})
.finally(() => {
console.log('Done!')
})
}
test()
finally()메소드는 앞에 then()이 실행되던 catch() 실행되던 마지막으로 실행하는 로직을 구성해줍니다.
async function test() {
try {
await a(8)
console.log('Resolve!')
} catch(error) {
console.log('Reject!')
} finally {
console.log('Done!')
}
}
test()
async와 await키워드 사용할 때 try, catch, finally는 위와 같이 작성하면 됩니다.
여기서 try는 방금 then과 같은 역할을 하고 있다는 것을 보면 됩니다.
'프론트엔드 > Vue.js' 카테고리의 다른 글
Vue Router 정리 (0) | 2023.08.31 |
---|---|
Vuex Helpers, 핵심 정리 (0) | 2023.08.31 |
컴포지션 API (0) | 2023.08.23 |
Vue문법(3) - 컴포넌트 (0) | 2023.08.23 |
Vue문법(2) - 바인딩, 렌더링, 핸들링 (0) | 2023.08.23 |