본문 바로가기
SeSAC

[새싹X코딩온] 풀스택 5주차 회고록 - 1 | 동기/비동기

by 리잼 2023. 8. 19.
반응형

동기, 비동기의 수업을 듣다가 제대로 이해하지 못한거 같아서 중요한 내용이니 만큼 자세히(내 기준..) 정리를 해보려고 한다..ㅜㅜ

동기( Synchronous )와 비동기 ( Asynchronous )

동기

  • 한 작업이 실행되는 동안 다른 작업은 멈춘 상태를 유지하고 자신의 차례를 기다리는 것
    이러한 동작을 단일 스레드 ( 싱글 스레드 ) 라고 부른다.

비동기

  • 특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고 다음 코드를 먼 저 실행하는 자바스크립트의 특성

순서대로 출력되는 js

callback 함수

  • JavaScript는 함수를 인자로 받고 다른 함수를 통해 반환될 수 있는데, 인자(매개변수)로 대입되는 함수를 콜백함수라고 함
  • 다른 함수가 실행을 끝낸 뒤 실행되는 함수
  • 함수를 선언할 때는 parameter(인자, 매개변수)로 함수를 받아서 쓸 수 있다.

callback 예시

function hello(name, cb) {
    const words = '안녕하세요 내 이름은 ' + name + ' 입니다.';
    cb(words);
}

hello('재민', (name) => {
    console.log(name);
});

hello('재민', (a) => {
    console.log(a);
});

위 코드는 어떻게 출력 될까?

매개변수의 이름과 상관없이 동일한 결과를 출력한다

즉 콜백 함수란 파라미터로 일반적인 변수 값을 전달하는게 아니라, 함수 자체를 전달 하는 것을 말한다.

 

function mainFunc(param1, param2, callback) {
    callback(param1 + param2);
    console.log('1 :', param1 + param2);
}

function callbackFunc(cb) {
    console.log('2 :', cb);
}

mainFunc(1, 2, callbackFunc);

위 코드의 결과는 ?

왜 1번이 아니라 2번이 먼처 호출 됐을까

mainFunc 에서 콜백 함수를 호출하고, console.log로 1번을 호출했기 때문이다.

js는 순서대로 코드를 처리하기 때문에 먼저 불러온 코드를 처리하고 그 다음 코드를 처리한다.

1번이 먼저 출력되게 하려면 순서를 바꿔주면 됨.

Callback 지옥

  • 비동기 프로그래밍 시 발생하는 문제 
  • 함수의 매개변수로 넘겨지는 콜백 함수가 반복되어 코드의 들여쓰기가 너무 깊어지는 현상
  • 가독성↓ 코드 수정 난이도↑

콜백지옥 예시

// 1. 1초 뒤에 body 태그의 색상을 빨간색 변경 (setTimeout)
            let body = document.querySelector('body');
            function change(cb) {
                setTimeout(function () {
                    body.setAttribute('style', 'color:red');
                }, 1000);
            }
            change();
            // 2. 1초 뒤에 body 태그의 색상을 빨 -> 1초 뒤 주 -> ... -> 1초 뒤에 파란색
            function change(cb) {
                setTimeout(function () {
                    body.setAttribute('style', 'color:red');
                    change2();
                }, 1000);
                function change2(cb) {
                    setTimeout(function () {
                        body.setAttribute('style', 'color:orange');
                        change3();
                    }, 1000);
                    function change3(cb) {
                        setTimeout(function () {
                            body.setAttribute('style', 'color:green');
                        }, 1000);
                    }
                }
            }
            change();

짧은 코드이지만 실무에서 수 많은 함수를 이런식으로 처리하고 유지보수를 해야 한다면 정신이 아득해 질 것이다..

이의 해결방안으로 Promise 라는게 있다.


Promise

  • 비동기 방식으로 작성된 함수를 동기 방식처럼 순서대로 실행할 수 있도록 만들 수 있다. ( 하지만 코드는 여전히 비동기 적으로 동작 )
  • 성공과 실패를 분리하여 반환
  • 비동기 작업이 완료된 이후에 다음 작업을 연결시켜 진행할 수 있는 기능을 가짐
  • ES6 에서 추가된 JS 문법

Promise의 상태

  • Pending (대기) : Promise를 수행 중인 상태
  • Fulfilled (이행) : Promise가 Resolve 된 상태 (성공)
  • Rejected (거부) : Promise가 지켜지지 못한 상태. Reject 된 상태 (실패)
  • Settled : fulfilled 혹은 rejected로 결론이 난 상태

Promise 사용법

Promise 는 두가지 콜백 함수를 가진다

  • resolve(value) : 작업이 성공(fulfilled)한 경우, 그 결과를 value와 함께 호출
  • reject(error): 에러(rejected) 발생 시 에러 객체를 나타내는 error와 함께 호출
			let body = document.querySelector('body');
            function change() {
                return new Promise((resolve, reject) => {
                    setTimeout(() => {
                        body.setAttribute('style', 'color:red');
                        resolve();
                    }, 1000);
                });
            }

            function change2() {
                return new Promise((resolve, reject) => {
                    setTimeout(() => {
                        body.setAttribute('style', 'color:orange');
                        resolve();
                    }, 1000);
                });
            }

            function change3(cb) {
                return new Promise((resolve, reject) => {
                    setTimeout(function () {
                        body.setAttribute('style', 'color:green');
                    }, 1000);
                });
            }

            change().then(change2).then(change3);

Promise 체이닝

  • Promise 는 then 메서드를 이용해 순차적인 작업이 가능하고
  • 코드 마지막 구문에 catch 를 이용해 예외처리도 가능하다

then 메서드를 이용해 순차적인 작업이 가능하다
catch를 이용한 예외 처리

catch 예외 처리는 다음 글에서 좀 더 다뤄보도록 하겠다.

async / await

  • 프로미스 기반 코드를 좀 더 쓰기 쉽고 읽기 쉽게 하기 위해 등장했다
  • 비동기 처리 패턴 중 가장 최근에 나온 문법

async

  • 함수 앞에 붙여 Promise를 반환한다
  • 프로미스가 아닌 값을 반환해도 프로미스로 감싸서 반환한다

await

  • 프로미스 앞에 붙여 프로미스가 다  처리 될 때까지 기다리는 역할을 하며 결과는 그후에 반환함

async가 붙은 함수는 항상 Promise를 반환한다

 

반응형