[자바스크립트/Javascript] 비동기처리의 이해
동기적 처리와 비동기처리
만약 작업을 동기적으로 처리한다면 작업이 끝날때까지 기다리는 동안 중지 상태가 되기 때문에 다른 작업을 할 수 없다. 그리고 작업이 끝나야 비로소 그 다음 예정된 작업을 할 수 있다.
하지만 이를 비동기적으로 처리한다면 흐름이 멈추지 않기 때문에 동시에 여러가지 작업을 처리할 수도 있고, 기다리는 과정에서 다른 함수도 호출할 수 있다.
예를 들어 연산량이 많은 작업을 처리하는 함수를 만들어보자.
function work() {
const start = Date.now();
for (let i = 0; i < 1000000000; i++) {}
const end = Date.now();
console.log(end - start + 'ms');
}
work();
console.log('다음 작업');
여기서 Date.now( )
는 현재 시간을 숫자 형태로 가져오는 자바스크립트 내장 함수이다.
위의 work( )
함수는 1,000,000,000번 루프를 돌고, 이 작업이 얼마나 걸렸는지 알려준다.
이 상태에서는 work( )
함수가 호출되면 for문이 돌아갈 때는 다른 작업은 처리하지 않고 온전히 for문만 실행하고 있다.
만약 이 작업이 진행되는 동안 다른 작업도 하고 싶다면 함수를 비동기 형태로 전환을 해주어야 하는데, 그렇게 하기 위해서는 setTimeout
이라는 함수를 사용해주어야 한다.
setTimeout
setTimeout 함수는 작업이 진행되는 동안 다른 작업도 하면서 함수를 비동기 형태로 전환한다.
우리가 정한 작업이 백그라운드에서 수행되기 때문에 기존의 코드 흐름을 막지 않고 동시에 작업들을 진행할 수 있다.
setTimeout을 통해 지정한 시간만큼 흐른 뒤에 작동하게 할 수 있다.
시간의 단위는 ms이다. 이 때 브라우저에서 지정한 최소 시간의 단위는 4ms이다.
setTimeout(() => {
}, 0) // 0 은 해당하는 시간만큼 흐른 뒤에 작동하겠다 를 의미
function work() {
setTimeout(() => {
const start = Date.now();
for (let i = 0; i < 1000000000; i++) {}
const end = Date.now();
console.log(end - start + 'ms');
}, 0);
}
console.log('작업 시작!');
work();
console.log('다음 작업');
setTimeout 함수의 첫번째 파라미터에 넣는 함수를, 두번째 파라미터에 넣은 시간(ms 단위)이 흐른 후 호출해준다.
지금은 두번째 파라미터에 0을 넣었지만, 실제로는 4ms 이후에 실행된다.
실행 결과를 보니, 작업이 시작되고 나서 for 루프가 돌아가는 동안 다음 작업도 실행되고, for 루프가 끝나고 나서 몇 ms 걸렸는지 나타나고 있다.
그렇다면 work 함수가 끝난 다음에 어떤 작업을 처리하고 싶다면 어떻게 해야할까?
이럴 땐, 콜백 함수를 파라미터로 전달해주면 된다!
콜백 함수란?
함수 타입의 값을 파라미터로 넘겨줘서, 파라미터로 받은 함수를 특정 작업이 끝나고 호출을 해주는 것을 의미한다.
function work(callback) {
setTimeout(() => {
const start = Date.now();
for (let i = 0; i < 1000000000; i++) {}
const end = Date.now();
console.log(end - start + 'ms');
callback(end - start);
}, 0);
}
console.log('작업 시작!');
work((ms) => {
console.log('작업이 끝났어요!')
console.log(ms +'ms 걸렸다고 해요.')
});
console.log('다음 작업');
- console.log('작업 시작') >>> 작업 시작
work( )
함수 호출 - for 구문 루프 시작- console.log('다음 작업') >>> 다음 작업
- console.log(end-start+'ms') 출력 >>> 910ms
work((ms) => {})
함수가 콜백 파라미터로 받아와서 for 구문 루프 작업이 끝난 뒤에callback(end-start)
가 호출된다. end-start 값이work((ms) => {})
ms
로 넘어온다. >>> 작업이 끝났어요! 910ms 걸렸다고 해요.
비동기적 처리 작업
주로 다음과 같은 작업들을 비동기적으로 처리하게 된다.
- Ajax Web API 요청: 만약 서버쪽에서 데이터를 받아와야 할 때는, 요청을 하고 서버에서 응답을 할 때 까지 대기를 해야 되기 때문에 작업을 비동기적으로 처리한다.
- 파일 읽기: 주로 서버쪽에서 파일을 읽어와야 하는 상황에는 비동기적으로 처리한다.
- 암호화/복호화: 암호화/복호화를 할 때에도 바로 처리 되지 않고, 시간이 어느 정도 걸리는 경우가 있기 때문에 비동기적으로 처리한다.
- 작업 예약: 단순히 어떤 작업을 몇 초 후에 스케쥴링 해야 하는 상황에는 setTimeout 을 사용하여 비동기적으로 처리한다.
비동기 작업을 다룰 때에는 callback 함수 외에도 Promise, async/await 이라는 문법을 사용하여 처리할 수 있다.