---
# System prepended metadata

title: 동기 비동기

---

# 동기 비동기

1. javascript 는 동기인가? 비동기인가? 
    - 동기
2. 비동기가 처리되는 과정
    - call stack에서 비동기인 경우(ajax, event, timing + promise) webapi를 호출하고  call stack에서 pop한다.
    - webapi는 수행을 완료한 비동기 함수(ex setTimeout의 시간이 다 지난 경우)의 콜백 함수를 태스크 큐에 넣는다.
    - 태스크 큐에서 대기하다가 call stack이 비는 시점에 태스크 큐 내의 함수가 call Stack에 push 된다.
    - ajax, event, timimg의 경우에는 task queue로 promise는 micro task queue로 들어간다. 수행은 마이크로태스크 큐가 먼저 동작한다.

```
콜백함수를 태스크 큐에 넣는 함수들

setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O, UI 렌더링

콜백함수를 마이크로태스크 큐에 넣는 함수들

process.nextTick, Promise, Object.observe, MutationObserver
```
 
4. forEach는 순서가 보장되는지
    - callback 함수가 동기인 경우에는 순서가 보장됨
    - 비동기인 경우에는 비동기 처리가 먼저되는 함수가 우선적으로 동작하여 순서가 보장되지 않음
        ```javascript
        var list = [4000, 2000];
        list.forEach(function(l, index) {
            console.log(l + ' started ...');
            setTimeout(function() {
                console.log(index + ': ' + l);
            }, l);
        });
        
        output:
        4000 started
        2000 started
        1: 2000
        0: 4000
        ```
        
        위의 코드의 경우 4000이 먼저 실행은 되지만 출력은 2000이 먼저 출력이 됨
        
5. forEach 전체를 기다리는 방법
    - forEach문의 callback 함수가 비동기인 경우 이벤트 큐에서 처리되기 때문에 
    ```javascript
    const forEachLoop = () => {
    console.log('Start');

    fruitsToGet.forEach(async fruit => {
        const numFruit = await getNumFruit(fruit);
        console.log(numFruit);
      })

      console.log('End');
    }
    ```
    위 코드에서는 Start -> End -> 과일명이 출력됨
    
    원래대로 forEach문 전체가 출력된 후 End를 출력시키기 위해서는
    Promise.all 혹은 for await 을 사용해야함
    ```javascript
    const forEachLoop = _ => {
        console.log('Start');
        const numFruits = [];
        fruitsToGet.forEach(async fruit => {
            numFruits.push(getNumFruit(fruit));
        })
        // 1
        for await (const numFruit of numFruits) {
            console.log(numFruit);
        }

        // 2
        const fruits = Promise.all(numFruits);
        console.log(fruits);

        console.log('End');
    }
    ```
    
    
    참조
    - https://new93helloworld.tistory.com/361
    - https://sustainable-dev.tistory.com/82
    - https://stackoverflow.com/questions/18983138/callback-after-all-asynchronous-foreach-callbacks-are-completed
    - https://joshua1988.github.io/web-development/javascript/javascript-asynchronous-operation/
    - https://engineering.linecorp.com/ko/blog/dont-block-the-event-loop/
    - https://velog.io/@wan088/JavaScript-EventLoop%EC%99%80-%EB%B9%84%EB%8F%99%EA%B8%B0-%EB%8F%99%EC%9E%91
    - https://meetup.toast.com/posts/89