동기 실행은 시작된 작업이 전부 처리되고 나서 다음 코드로 넘어가는 것이다. 즉 코드가 보이는 대로 실행된다.
특정 작업을 시작하고, 그것이 완벽하게 다 처리되기 전에 실행 흐름이 다음 코드로 넘어가고, 나중에 콜백이 실행되는 것을 비동기 실행이라고 한다.
아래의 예시 코드를 보자
console.log("start"); fetch("https://www.google.com") .then((response) => response.text()) .then((result) => console.log(result)); console.log("end");
실행결과
console.log("start")
와 console.log("end")
가 먼저 실행되고, 그 뒤에 .then
으로 등록한 callback 함수가 실행되었다. 따라서 fetch
함수 실행 후에 비동기 실행으로 console.log("end")
함수가 먼저 실행된 것을 알 수 있다.
만약에
fetch
함수가 동기 실행을 한다고 가정한 경우와 그렇지 않은 경우를 그림으로 나타내었다.
이렇게 비동기 실행을 하면 이점은 무엇일까? 바로 시간 절약이다. 위의 그림처럼 fetch
함수 실행 후 리스폰스가 오기 전에 다음 코드를 실행하면 대기하는 동안의 시간 손실이 그만큼 줄어드는 것이다.
async/await
문법으로 비동기 실행이 어떻게 진행되는지 알아보자.
async function asyncTest() { console.log(2) const response = await fetch("https://www.google.com") console.log(7); const result = await response.text() console.log(result) } console.log(1); asyncTest() console.log(3); console.log(4); console.log(5); console.log(6);
위의 코드는 1 -> 7로 진행된다. 먼저 console.log(1)
이 실행되고, asyncTest
함수가 실행된다. 이때 console.log(2)
가 실행된 후 await 문법으로 실행된 fetch
함수의 리스폰스가 올때까지 asyncTest
함수의 밖으로 나가서 console.log(3~6)
이 순차적으로 실행된다. 그리고 다시 asyncTest
함수 안에서 리스폰스가 오면 console.log(7)
이 실행되고 나머지 코드들이 실행된다.
이처럼 async/await도 비동기 실행이기 때문에 리스폰스가 올 때까지 외부의 코드들이 실행된다.
① Call Stack에 비동기 함수가 호출되면 Web API로 이동된다.
② 비동기 함수 이벤트 발생 시(리스폰스 도착) 콜백 함수를 Task Queue로 이동된다.
③ Event Loop가 Call Stack이 비어있는지를 확인하고, Call Stack이 비워져 있으면 Task Queue에 있는 콜백 함수를 Call Stack에 넘겨준다.(console.log(3~6)실행 후)
특정 함수의 실행을 원하는 시간만큼 뒤로 미루기 위해서 사용.
2초 후에 실행
console.log(1); setTimeout(() => {console.log(2)}, 2000); console.log(3);
단, 비동기 실행 함수는 Call Stack이 비워져 있어야 실행되므로, 2초가 지났어도 Call Stack이 비워져 있지 않다면 실행되지 않는다. 따라서 원하는 시간 뒤에 실행되지 않는 경우가 있을 수도 있으니 주의해야 한다.
특정 콜백을 일정 시간 간격으로 실행하도록 등록하는 함수.
2초 간격으로 실행
console.log(1); setInterval(() => {console.log(2)}, 2000); console.log(3);
click 등과 같이 특정 이벤트가 발생했을 때 실행할 콜백 함수 등록.
click 이벤트가 발생해야만 콜백 함수가 실행됨.
button.addEventLitener('Click', () => { console.log('hello world'); }