# Asynchronous Programming In Javascript - Event Loop

# 1\] Synchronous and Asynchronous Actions

![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwGDFQbmlCnk6-jSsaJ5kixE5Z5YlLEM95fzzIdKXZkHgzPFhPlzVN5XhIdgdvp2YcEeWh_28Bo8u6fq0QtVDdr9WmkUyHyfEtlSJAQYk7eESrHEVWvW5HieX5KYkTEmHu8ZaALnxkc8CEemXk4k8ZBEGjfeXhAXYS9tOR2E69g5rSTHCnw-s80ZlffO0f/w640-h294/sync%20actions%20and%20async%20actions.drawio.png align="left")

동기 처리의 경우, 함수를 호출한 후, return이 올 때 까지 기다린다. 그 후 다음 statement를 진행한다.

비동기 처리의 경우, 함수를 호출하고 return을 기다리지 않고 바로 다음 statement를 진행한다. 그 후 callback이 실행이 된다.

# 2\] Example of Asynchronous Actions

1. setTimeout
    
2. HTTP requests 보내기
    
3. reading and writing data to files(파일에서 읽기와 파일에 쓰기)
    
4. DB에 query 보내기 등...
    

# 3\] Event Loop in Javascript

![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2EAzibRYPs51qEQ7BIMLDsAIuSwOT4LNmXvrI-eZiZbtazulaOVdeHUQ_B_M1urFHNanJnwmbEtIoCmO6-R9BSS-xJNGJ4VOI9cSp_AcabWHJsakslmiPGu-UioQrS9vtiZuDSVvI9D2kk5Pmu31QVwjH-Kq5vwhqFVSFcD4cAtZlXfPHvnQQQ3rhhu-8/w640-h624/el%20and%20functions.PNG align="left")

Javascript는 위 그림과 같이 fucntion one(), two(), three(), four()를 생성하고 실행시켰을 경우, 다음과 같이 진행된다.

1. Global execution context을 만들고 Call stack에 넣는다.
    
2. 이렇게 모든 함수를 선언하면 밑에 쓰여진 대로 one() 에 도달하게 된다.
    
3. 새로운 Execution context를 Call stack의 맨 위에 생성한다.(이 Execution context는 인자, 지역변수와 함께 one()를 나타낸다.)
    
4. one()으로 들어가서, 실행하고, 끝나면 Call stack 맨 위의 execution context(새로 추가한 execution context)를 제거한다.
    
5. 똑같이 two()에 도달하면, 새로운 Execution context를 생성하고, two() 안의 getNumber2()가 새로운 함수이기 때문에 또 새로운 Execution context를 생성한다.
    
6. 그 후, getNumber2()가 리턴되고, EC(Execution context)가 제거되며, two()가 리턴되고, EC가 또 제거된다.
    
7. **three()로 들어가서 새로운 EC를 생성하고 실행하는데, setTimeout이 비동기 함수이기 때문에, Javascript가 리턴을 기다리지 않는다. 따라서 다음으로 이동한다.**
    
8. **따라서 EC를 제거하고, four()로 가서 새로운 EC를 생성한다.**
    
9. **setTimeout이 끝났을 경우, console.log(3)을 실행하는 것이 아니라, 이 새로운 task를 Message queue(Task queue)에 추가한다. 이 task는 callback에 대한 참조가 있다.**
    
10. 이 callback은 Call stack이 비지 않았으므로 실행이 되지 않고, four()가 실행되고, EC를 제거한다.
    
11. 끝에 도달하면, Global execution context가 Call stack에서 제거된다.
    
12. Call stack이 빌 때마다, Javascript engine은 Message queue에 뭔가 있는지 확인한다.
    
13. 이 때는 1개의 task가 Message queue에 있게 되므로, Javascript engine은 Message queue에서 task를 가져와 Call stack에 새로운 EC를 생성한다.
    
14. 그 후 오직 callback만을 실행하고 끝나면 EC가 call stack에서 제거된다.
    
15. 그러면 Javascript가 Call stack을 체크하고, 없으면 Message queue를 다시 체크한다.
    
16. 다 없으므로, Javascript engine이 종료된다.
    

따라서 결과는 1 2 3 4 가 아닌 1 2 4 3 이 나오게 된다.

# 4\] Fix

four()를 three() 안에 넣어주면 된다.

```javascript
function three() {
  setTimeout(function () {
    console.log(3);
    four();
  }, 0);
}
```
