#동기, 비동기
Synchronous
동기 : 요청을 보낸 후 해당 요청의 응답을 받아야 다음 동작을 실행하는 방식Asynchronous
비동기 : 요청을 보낸 후 응답과 관계없이 다음 동작을 실행하는 방식
자바스크립트에서 CPU의 계산에 의해서 즉시
처리가 가능한 대부분의 코드는 동기적으로 작동하게 됩니다.
또한 계산식이 복잡해서 CPU 가 계산하는데 시간이 많이 걸리더라도 동기적으로 작동하게 됩니다.
하지만 !
- 사용자의 요청에 의해 특정 시간이 경과되기 전까지 함수의 실행을 보류하는 상황(
SetTimeout
,setInterval
) - 사용자의 직접적인 개입이 있을때 비로소 함수를 실행하도록 대기하거나 (
addEventListener
) - 웹 브라우저 자체가 아닌 별도의 대상에 요청을 하고 그에 대한 응답을 받고나서 어떤 함수를 실행하는 작업(
XMLHttpRequest
기반의Fetch
,Axios
)
를 통틀어 요청, 실행 대기, 보류 와 관련된 코드는 비동기적 코드입니다.
현대 자바스크립트에서 복잡도에 따라 비동기적 코드의 비중이 높아졌고, callback 함수를 익명함수로 전당하는 과정을 반복하면서 들여쓰기가 반복되는 상황인 callback 지옥
이라는 말도 생기게 되었습니다.
이러한 비동기 처리
과정의 다양한 방법을 차례대로 살펴보겠습니다.
#Synchronous 동기
function getData() {
const data = {'data': 'some data'}
return data
}
let response = getData()
console.log(response) // {'data': 'some data'}
즉각적인 데이터를 return 해주게 됨으로 원하는 response 를 바로 얻을 수 있습니다.
#Asynchronous 비동기 ( setTimeout )
function getData() {
let data
setTimeout(function() {
console.log('요청을 보냈습니다')
data = {'data': 'some data'}
}, 1000 )
return data
}
let response1 = getData()
console.log(response1)
// undefined - setTimeout 전에 출력
// (1000ms later ... )
// 요청을 보냈습니다
1000ms 의 대기시간 후에 data 값이 할당되게 되는데 기다리지 않고 할당되지않은 data가 return 됩니다.
#CallBack function
function getDatacallback(callback){
setTimeout(function() {
const data = {'data':'some data'} // 데이터 도착
callback(data) // 내가 원하는 작업 시작
},1000)
}
// 함수 호출, 인자로 함수를 넘겨주는데 그게 출력하는 작업
getDatacallback(function(data) {
console.log(data)
})
getDatacallback 함수에 data를 출력하는 함수를 callback 함수로 담아서 실행시키게 됩니다.
그러면 setTimeout 내에서 동작이 이루어 진 후 넘겨주었던 callback 함수에 data를 담아서 실행하게 됩니다.
#promise
function getDataPromise() {
return new Promise(resolve => {
setTimeout(function() {
const data = {'data':'some data'}
resolve(data) // 내가 원하는 작업 시작
},1000)
})
}
let response3 = getDataPromise()
console.log(response3) // Promise {<pending>}
// 함수 실행 후 then 으로 resolve 함수를 요청할 수 있습니다.
response3.then(response => console.log(response))
getDataPromise()
.then(response => console.log(response))
비동기처리를 하기 위한 promise API 입니다.
기본적으로 Promise 객체는 해당 비동기 작업이 끝나게 되면 resolve 함수를 호출하는 방식으로 동작하게 됩니다.
#async / await
function getDataPromise() {
return new Promise(resolve => {
setTimeout(function() {
const data = {'data':'some data'} // 데이터 도착
resolve(data) // 내가 원하는 작업 시작
},1000)
})
}
async function printData() {
const data = await getDataPromise()
console.log(data)
}
printData()
기본적으로 Promise로 구성이 되어있고, fetch, axios 도 물론 사용할 수 있습니다.
함수 앞에 async 를 이용하여 비동기처리를 할 수 있게 해주고 비동기 함수에 대해서 await 를 통하여 동작시켜주면 getDataPromise 가 동작할때까지 대기를 한 후에 그 다음 동작이 이루어 지게 됩니다.
비동기 작업의 동기적 표현을 가능하게 해주어 가독성도 뛰어나면서 작성도 간편한 코드입니다.
#Promise, async/await 에 대하여
- 요청받은 데이터를 이용하여 또 다른 요청을 보내는 경우 ( chaining )
- 잘못된 값이나 오류의 처리 과정 ( reject , .catch, try catch )
- axios 와 async / await
위 과정들에 대하여 좀 더 자세히 정리 후에 포스팅 ( 비동기 처리 )하겠습니다.