동기와 비동기

Jun·2022년 5월 11일
0

네이버 부스트캠프

목록 보기
13/21

동기와 비동기


동기는 순차적으로 테스크를 수행하고, 비동기는 병렬적으로 수행한다.

동기 (Synchronous)


  • 동기는 요청을 보낸 후 응답을 받아야지만 다음 동작이 이루어지는 방식을 말한다. 모든 일은 순차적으로 실행되며 어떤 작업이 수행 중이라면 다음 작업은 대기한다.
  • 예를 들자면, 카페에서 주문을 하나 받고 음료 제조하고, 다시 주문 하나 받고 음료 제조하는 방식이다.
const f1 = () => {
  console.log('hello');
  f2();
};

const f2 = () => {
  console.log('world');
  f3();
};

const f3 = () => {
  console.log('!!');
};

f1(); //f1 -> f2 -> f3

비동기 (Asynchronous)


  • 비동기는 요청을 일단 다 받은 다음에, 요청이 끝나면 테스크가 순차적으로 수행되는 방식이다.
  • 예를 들자면, 카페에서 주문을 모두 받은 뒤, 음료를 제조하는 방식이다.
const f1 = () => {
  console.log('hello');
  f2();
};

const f2 = () => {
  setTimeout(() => {
    console.log('world');
  });
  f3();
};

const f3 = () => {
  console.log('!!');
};

f1(); //f1 -> f3 -> f2

비동기 처리는 왜 필요한가?

  • 데이터를 서버로부터 받아오는 앱을 만든다고 가정해보자.
    서버로부터 데이터를 받아와서 해당 데이터를 처리해야하므로, 데이터를 받아오는 코드는 제일 상단에 위치할 것이다.
  • 이때, 비동기로 처리하지 않고 동기적으로 처리한다면, 데이터를 받아올 때까지 기다린 다음에 다음 코드가 실행될 것이다.
  • 만약 받아올 데이터의 크기가 크다면, 그 동안 앱은 멈춰있을 것이다.
  • 따라서 이러한 불편함을 없애기 위해, 데이터의 수신같은 기다려야하는 코드들은 비동기적으로 처리한다.

자바스크립트에서 비동기


비동기 처리를 위한 콜백 패턴의 단점

  • 자바스크립트에서 비동기 처리를 위해 클로저나 람다식을 인자로 넣어 콜백 처리를 수행한다.
  • 만약 이 콜백 처리의 양이 상당이 많아진다면, 콜백 헬 ( 콜백 함수 호출이 중첩되어 복잡도가 높아지는 현상)이 발생하고, 이는 에러처리 또한 힘들게 된다.
  • 콜백 헬

다운로드_(8)

Promise

  • 위의 콜백 헬을 극복하기 위해 ES6에서 Promise가 도입되었다

    const promise = new Promise((resolve, reject) => {
    	// 콜백 함수 내부에서 비동기 처리를 수행한다.
    	if (// 비동기 처리 성공) {
    		resolve('success');
    	} else { // 비동기 처리 실패
    		reject('fail');
    	}
    }
    
    promise
    	.then(value => {
    		console.log(value); //success 출력
    	})
    	.catch(error => {
    		console.log(error);
    	})
  • Promise란 내용이 실행은 되었지만 결과를 아직 반환하지 않은 객체를 의미한다.

  • 즉 위의 promise변수에 Promise객체가 저장되고, 이는 나중에 결과 값을 가져와 사용할 수 있다는 것을 의미한다.

  • 그리고 Promise를 생성할 때, 콜백 함수를 인자로 넘겨 주는데, 그 콜백안에 두 개의 콜백함수를 또 넘겨준다. (resolve, reject)

  • 이 두 콜백은 각각 비동기 처리의 성공, 실패 여부에 따라 수행된다.

  • 만약 성공했다면 resolve 함수를 통해 success라는 메시지가 전달된다.

  • 이렇게 생성한 프로미스를 사용하기 위해서 then이라는 기능을 사용한다.

  • then에서 value는 resolve에서 전달한 메시지가 전달된다.

  • 만약 resolve가 아니라 reject (실패)라면 then 이 아닌 catch를 이용하여 진행한다.

Promise Chaining

  • 순차적으로 처리해야하는 비동기 작업이 여러개 있다고 할 때, Promise Chaining을 한다면 이를 해결할 수 있다.
const fetchNumber = new Promise((resolve, reject) => {
  setTimeout(() => resolve(1), 1000); // (*)
});

fetchNumber
  .then(num => num * 2) // (**)
  .then(num => num * 2) // (***)
  .then(num => {
    return new Promise((resolve, reject) => {
      setTimeout(() => resolve(num), 1000);
    });
  })
  .then(num => console.log(num)); // 4
  1. 1초 후 최초 프라미스가 이행됩니다. – (*)
  2. 이후 첫번째 .then 핸들러가 호출됩니다. –(**)
  3. 2에서 반환한 값은 다음 .then 핸들러에 전달됩니다. – (***)
  4. 이런 과정이 계속 이어집니다.

스크린샷_2021-08-04_오전_12 45 20

  • 프로미스 체이닝이 가능한 이유는 then을 호출하면 프로미스가 반환되기 때문입니다.
profile
HiHi

0개의 댓글