🐱자바스크립트 비동기

2019. 03. 16

sat10am

Seungwoo Hong

😎 자바스크립트의 비동기

: Part 1

🏁 시작 부터

😎 자바스크립트는 싱글스레드!

😎 자바스크립트는 싱글스레드!

싱글 스레드 == 스택이 하나 == 한 번에 하나의 일만 한다.

    
    function add(x, y) {
        return x + y;
    } 
    
    function printAddedNumber() {
        let sum = add(1, 2);
    
        console.log(sum);
    }
    
    
    printAddedNumber();

✌️ Example code

📚 Call stack

step 을 하나 하나를 Stack frame이라 한다.

🏃‍♀️ Run to completion

실행 되고 있는 작업이 있다면 다른 작업은 중간에 끼어들 수 없다.

그런데 스택 처리 시간이 오래 걸리면?

😩 그냥 대기ㅠㅠ

😩 아니 그럼 동시성을 지원 안해?

👏 The solution

Asynchronous Callback !!

(비동기 콜백)

🐝 Runtime

    
    console.log('foo');
    
    setTimeout(function() {
        console.log('bar')
    }, 10 * 1000);
    
    console.log('baz');

✌️ Example code

🤖 Role

Call Stack - 함수가 호출 되면 상단에 Push, 종료되면 pop

Heap - 메모리 할당이 일어나는 곳

Task queue - 전달 받은 콜백함수를 저장하는 큐(FIFO)

Event loop - Call stack을 감시, 비어 있으면 콜백 전달

🎃 Event loop

    
    while(queue.waitForMessage()){
      queue.processNextMessage();
    }

  waitForMessage() 의 역할은 다음과 같다

  1. 테스크가 들어 올때까지 기다리는 역할을 한다.

  2. 실행 중인 테스크 큐가 있는지 감시

 

이벤트 큐는 위와 같은 역할을 반복 수행 하여 테스크를 스택에 전달한다.

🎃 Event loop

    
    function delay() {
        for (var i = 0; i < 100000; i++);
    }
    function foo() {
        delay();
        console.log('foo!');
    }
    function bar() {
        delay();
        console.log('bar!');
    }
    function baz() {
        delay();
        console.log('baz!');
    }
    
    setTimeout(foo, 10);
    setTimeout(bar, 10);
    setTimeout(baz, 10);

 - 자바스크립트는 싱글 스레드이다.

 - 동시성을 구현하기 위해 콜백을 사용

 - 자바스크립트 엔진은 Heap, Stack, Event loop, Task Queue가 존재

 - 동작 순서

    1. 기본 함수는 스택에 쌓이고 종료 되면 스택을 빠져나온다.

    2. 비동기 콜백은 스택에 잠시 쌓인다. 그리고 바로 빠져나와 데스크큐에 추가 된다.

    3. 콜백 함수가 실행 될 시점이 되면 이벤트 루프는 call stack이 비어 있는 걸 확인 하고 익명함수를              집어넣고 익명 함수는 실행 후 call stack을 빠져나온다. (이벤트 루프의 작업을 tick이라고 부름)

🐹 Summary

 👾 Callback function

콜백 함수란 함수의 인자로 전달 되어 이벤트가 발생 되면

필요에 따라 즉시 실행 될 수도 나중에 실행 될 수도 있는 함수

🐶 비동기 vs 동기

동기 - 시간 흐름 순으로 작업이  진행 되며 진행 중인 작업이 완료 될때 까지

          다른 작업 이 중간에 선점 하지 못한다.

 

비동기 - 작업이 완료 되지 않은 상태에서 해당 작업을 다른 이에게 위임하고 다음

             작업을 진행 한다.  그리고 위임한 작업이 완료 되면 작업을 결과물을 가져온다.

👽 동기 콜백

콜백 함수란 함수의 인자로 전달 되어 이벤트가 발생 되면

즉시 실행되는 함수

👽 동기 콜백

    
    function greeting(name) {
        console.log(`hello ${name}`);
    }
    
    function processUserName(name, callback) {
        callback(name);
    }

    console.log('hi');
    processUserName('hong', greeting)
    console.log('again hi');

😼 비동기 콜백

콜백 함수란 함수의 인자로 전달 되어 이벤트가 발생 되면

나중에 실행 될 수도 있는 함수

😼 비동기 콜백

    
    console.log('hi');
    setTimeout(function() {
        console.log('see you later')
    }, 1000)
    console.log('again hi');

😼 비동기 콜백 사례

 - Web API

 - AJAX

 - DOM

👿 콜백함수의 한계

 - Callback hell

 - 예외 처리

👿 Callback hell

5까지 1초마다 1씩 더하고 싶다.

setTimeout(function() {
  let sum = 1;
  console.log(sum, "초");

  setTimeout(function() {
    sum += 1;
    console.log(sum, "초");

    setTimeout(function() {
      sum += 1;
      console.log(sum, "초");

      setTimeout(function() {
        sum += 1;
        console.log(sum, "초");

        setTimeout(function() {
          sum += 1;

          console.log("sum:", sum);
        }, 1000);
      }, 1000);
    }, 1000);
  }, 1000);
}, 1000);

👿 Callback hell 해결

let sum = 1;

function start() {
  console.log(sum, "초");
  setTimeout(firstPlus, 1000);
}

function firstPlus() {
  sum += 1;
  console.log(sum, "초");

  setTimeout(secondPlus, 1000);
}

function secondPlus() {
  sum += 1;
  console.log(sum, "초");

  setTimeout(thirdPlus, 1000);
}

function thirdPlus() {
  sum += 1;
  console.log(sum, "초");

  setTimeout(fourthPlus, 1000);
}

function fourthPlus() {
  sum += 1;
  console.log("sum:", sum);
}

setTimeout(start, 1000);

👿 예외처리

 

❗️ 오류를 감지를 못하다니..

    
    try {
        setTimeout(function() {
            throw 'error'; 
        }, 10)
    } catch(e) {
         console.log(e);   
         console.log('에러 잡았다');
    }

👿 예외 처리 오류 해결1

 

비동기 함수 안에서 예외처리

    
    setTimeout(function() {
        try {
            throw 'error'; 
            
        } catch(e) {
             console.log(e);   
             console.log('에러 잡았다');
        }
    }, 10);

👿 예외 처리 오류 해결2

    
    function errorHandler(process) {
      return function() {
        try{
          return process.apply(this, arguments);
          console.log(arguments);
    
        } catch(e) {
          console.log(e);
          console.log('에러에서 복구됐다.');
        }
      };
    }
    
    setTimeout(errorHandler(function() {
      throw '에러가 발생했다!';
    }), 1000);
    

🐹 Summary

 - 콜백 함수란 함수의 인자로 전달 되어 이벤트가 발생 되면

    나중에 실행 될 수도 있는 함수

 - 동기 콜백과 비동기 콜백이 있다.

 - DOM, AJAX, Web API에서 유용하게 사용된다.

 - 콜백 지옥과 예외 처리 오류 문제가 있다