javascript 동기 비동기

jimin·2022년 5월 29일
0

nodeJs

목록 보기
3/5
post-thumbnail

동기와 비동기

동기(Synchronous) : 동시에 일어난다.

비동기(Asynchronous) : 동시에 일어나지 않는다.

동기

요청을 순차적으로 해결 (직렬적 테스크 수행)

  • 요청을 보냈다면, 응답을 받아야 다음 동작이 이루어진다.
  • 요청과 결과가 한자리에서 동시에 일어난다.
  • 순차적으로 실행되기 때문에, 어떤 작업이 수행중이라면 다음 작업은 대기해야 한다.

장점 : 설계가 매우 간단하고 직관적이다.

단점 : 결과가 주어질때까지 아무것도 못하고 대기해야 한다.

비동기

요청을 순차적으로 해결하지 않음 (병렬적 테스크 수행)

  • 작업 종료 여부에 관계 없이 다음 작업을 실행한다.
  • 요청한 그 자리에서 결과가 주어지지 않는다.

장점 : 결과가 주어지는데 시간이 걸리더라도 그 시간 동안 다른 작업을 할 수 있으므로 자원을 효율적으로 사용할 수 있다.

단점 : 동기방식보다 복잡하다.

자바스크립트는 동기적 언어인 것 같다.

아래의 자바스크립트 엔진 사진을 보면 왜 자바스크립트가 동기적 언어인지 알 수 있다.

Memory Heap : 변수와 객체 메모리 할당

Call Stack : 함수가 호출이 되면 쌓이는 곳 LIFO 구조 (먼저 들어온것이 먼저 나간다.)

자바스크립트는 기본적으로 싱글 쓰레드 기반의 언어이다.
호출 스택이 하나인데 LIFO 구조로 동작하기 때문에 언어 자체는 동기적 언어인것같다.


하지만 우리는 자바스크립트를 비동기라고 생각한다.
console.log("시작");

setTimeout(function(){
    console.log("3초후 실행");
}, 3000);

console.log("끝");

// 시작
// 끝
// 3초후 실행

그 이유는 자바스크립트 런타임을 보면 알 수 있다.

이벤트 루프가 이벤트를 감지 하고 특정 이벤트가 발생하면 Web api에서 동작후 그 결과 값을 콜백 큐에 담습니다.

그 후 콜 스택에서 실행되는 작업이 모두 완료되면 큐에 담겨있던 콜백 함수들이 스택으로 옮겨가게 된다.

(setTimeout이나 HTTP 요청 메서드, DOM 이벤트 등의 메서드는 자바스크립트 엔진에서는 지원하지 않고 Web Api에서 지원합니다.)

자바스크립트의 비동기를 처리하는 프로그래밍

콜백함수

다른 함수의 인자로써 넘겨진 후 특정 이벤트에 의해 호출되는 함수.

// 즉시 실행, 동기적으로 실행되고 있는 함수(funName)의 콜백함수 callbackFun
function funName (callbackFun) {
  callbackFun()
}  

콜백 함수를 인자로 넘겨주면서 비동기 작업의 처리를 요청하는 코드의 예시

  • setTimeout() 함수 : 특정 시간이 경과하면 인자로 넘긴 콜백 함수가 호출되도록 웹 API에 요청한다.
    setTimeout(function () {
        console.log('Hello World');
    }, 1000);
  • Ajax 요청 : 요청에 대한 응답이 날아오면 인자로 넘긴 콜백 함수가 호출되도록 웹 API에 요청한다.
    $.get('https://xyz.com/students/0', function (response) {
        console.log(response);
    });
  • 이벤트 핸들러 등록 : 해당 이벤트의 발생이 감지되면 인자로 넘긴 콜백 함수가 호출되도록 웹 API에 요청한다.

단점 :

  • 콜백 지옥
    obj.callback(parameter1, () => {
      obj.callback(parameter2, () => {
          obj.callback(parameter3, () => {
              obj.callback(parameter4, () => {
                  obj.callback(parameter5, () => {
                      obj.callback(parameter6, () => {
                          console.log('Hello, World!')
                      })
                  })
              })
          })
      })
    })
    ``
  • 에러 핸들링과 예외 처리가 힘들다.

Promise

비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타내는 객체

콜백의 예외처리가 어렵다는 것과 중첩으로 인한 복잡도가 증가한다는 단점을 해결하기 위해 생겨난 자바스크립트 비동기 처리에 사용되는 객체

const promiseName = new Promise((resolve, reject) => {
	// ...
});

프로미스의 상태

프로미스는 다음 중 하나의 상태를 가집니다.

  • 대기(pending): 이행하거나 거부되지 않은 초기 상태.
    new Promise();
     
    new Promise(function(resolve, reject) {
      // ...
    });
  • 이행(fulfilled): 연산이 성공적으로 완료됨.
    new Promise(function(resolve, reject) {
      resolve();
    });
    이행 상태에서 then()을 이용하여 처리 결과 값을 받을 수 있다.
    promiseName
      .then((result) => {
    		console.log(result);
    	})
  • 거부(rejected): 연산이 실패함.
    new Promise(function(resolve, reject) {
      reject();
    });
    거부 상태에서 catch()을 이용하여 실패 처리의 결과 값을 받을 수 있다.
    promiseName
    	.catch((error) => {
    		console.log(error);
    	});

에러 처리법

  • then()의 두 번째 인자로 에러를 처리하는 방법
    getData().then(
      handleSuccess,
      handleError
    );
  • catch()를 이용하는 방법
    getData().then().catch();

async/await

const funName = async () => {
    const result = await asyncFunc() 
    console.log(result)
}

async

async 함수를 실행하게 되면 무조건 Promise 객체가 반환된다.
async 함수 내에서 return은 반환된 Promise 객체의 결과(resolve)값이다.

async function f() {
  return 1; // 리턴인 1인 이행 프라미스가 반환
}

await

await 키워드는 반드시 async함수 안에서만 사용할 수 있다.

let value = await promise; 
//일반 함수안에 사용시 Syntax error 발생

기존 promise와의 차이점

  • 에러
    • Promise 를 활용할 시에는 catch() 문을 통해 에러 핸들링이 가능하지만, async/await 은 에러 핸들링 할 수 있는 기능이 없어 try-catch() 문을 활용해야 한다
  • 코드 가독성
    • Promise의 then() 지옥의 가능성
    • 코드가 길어지면 길어질수록, async/await 를 활용한 코드가 가독성이 좋다.
    • async/await 은 비동기 코드가 동기 코드처럼 읽히게 해준다. 코드 흐름을 이해 하기 쉽다.


javascript의 동기 비동기는 항상 공부를 하면서도 정확하게 알지 못했는데 지금 제가 이해하는 대로 적어보았습니다. 틀린 내용이 있다면 댓글 적어주세요

출처
https://developer.mozilla.org/
https://blog.sessionstack.com/how-does-javascript-actually-work-part-1-b0bacc073cf
https://ko.javascript.info/

profile
안녕하세요 백엔드 개발자 지민입니다.

0개의 댓글