네트워크 통신, 동기/ 비동기

LEE JI YOUNG·2022년 3월 11일
0

JS/Node

목록 보기
14/23

자바스크립트는 일반적인 코드를 작성하면 synchronous(동기적) 하게 처리.
: JS는 동기적(synchronous)이다. 호이스팅 후 동기적으로 위에서부터 코드가 실행된다.
자바스크립트는 어떤 함수들을 사용하면 asynchronous(비동기적) 하게 코드실행이 가능.

  • 보통 Promise(비동기 객체) 안에선 조금 헤비한 일들을 수행한다 : 네트워크에서 데이터를 받아오거나, 파일에서 무언가 큰 데이터를 읽어오는 과정은 시간이 필요하다. 이런 것을 동기적으로 처리하게 되면 이 오래걸리는 일들을 수행하는 동안 다음라인의 일이 수행되지 않는다. 그래서 시간이 조금 걸리는 일은 프로미스를 만들어서 비동기적으로 수행해준다.

    --> fetch : javascirpt 비동기 통신중 하나. fetch 함수 자체가 Promise 객체를 Return하기에 편하다.

네트워크 통신시 비동기 처리 !!

https://www.youtube.com/watch?v=s1vpVCrT8f4

  • 비동기 프로그래밍은 무엇인가 ?
  • 어떻게 사용하는 것이 더 좋은지 ?
  • 현업에서는 어떤 경우에 어떻게 사용하는 것이 조금 더 맞는지 ?

  • hoisting: var 변수와, 함수 선언들이 자동적으로 가장 위로 올라가는 것.
  • 콜백함수 : 우리가 전달해준 함수를 나중에 니가 불러줘 ?
  • synchronous (동기적) : 정해진 순서에 맞게 코드가 실행됨.
// 실행순서 : 동기적 : 1 > 2 > 3
console.log('1');
console.log('2');
console.log('3');
  • asynchronous (비동기적) : 비동기적으로 언제 코드가 실행 될지 예측할 수 없는 것.
    • setTimeout() : 브라우저에서 제공하는 Web API. 지정한 시간이 지나면 전달한 콜백함수를 호출하는 것.
// 실행순서 : 비동기적 : 1 > 3 > 2
console.log('1');
setTimeout(function(){
	console.log('2');
}, 1000);
//간단하게 쓰는법 : setTimeout(() => console.log('2'), 1000);
console.log('3');
// setTimeout은 브라우저에게 요청을 하게됨. 1초 뒤 브라우저가 콜백함수 실행하게 한다.
  • Promise: 자바스크립트에서 제공하는 비동기를 간편하게 처리할 수 있게 도와주는 오브젝트.
    정해진 장시간의 기능을 수행하고나서, 정상적으로 기능이 수행되었다면 성공의 메세지와 함께 처리된 결과값 전달, 만약 기능을 수행하다가 예상치 못한 문제가 발생되었다면 에러를 전달해준다.
    Promise is a Javascript object for asynchrounous operation.

  • 콜백함수는 방법에 따라 동기적, 비동기적(setTimeout을 사용한 함수.) 실행이 가능하다.

  • JS 함수 사용법

    • 인자로 다른 함수에 전달(= 콜백형태)할 수 있다.
    • 변수에 할당해서 사용 할 수 있다.

콜백지옥 예시


  • 콜백함수 문제점 : 가독성이 너무 많이 떨어진다. 비지니스로직을 한눈에 알아보기 어렵다. 체인이 길어질수록 에러발생, 디버깅, 문제분석, 유지보수가 어렵다.

Promise

  • Promise: 자바스크립트에서 제공하는 비동기를 간편하게 처리할 수 있게 도와주는 오브젝트.
    정해진 장시간의 기능을 수행하고나서, 정상적으로 기능이 수행되었다면 성공의 메세지와 함께 처리된 결과값 전달, 만약 기능을 수행하다가 예상치 못한 문제가 발생되었다면 에러를 전달해준다.
    Promise is a Javascript object for asynchrounous operation.

  • Promise에서 고려할 포인트 2가지

      1. State : pending -> fulfilled or rejected
      • pending(프로미스가 만들어져서 우리가 지정한 operation이 수행중일때 상태)
      • fulfilled(operation을 성공적으로 끝냈을 때 상태. 완료상태)
      • rejected(파일을 찾을 수 없거나 네트워크에 문제가 생겼을 때 상태)
    • 2 . Producer(정보제공자) vs. Consumer(정보소비자)
      • Producer : 우리가 원하는 기능을 수행해서 해당하는 데이터를 만들어내는 것. 즉, Promise Object : resolve, reject 정의.
      • Consumer : 우리가 원하는 데이터를 소비하는 것. : then, catch, finally 사용
  • Promise는 class이기 때문에 new Promise()로 생성가능.

  • Promise의 executor라는 콜백함수를 전달해줘야한다. 이 executor라는 콜백함수가 resolve(기능을 정삭적으로 수행해서 마지막에 최종 데이터를 전달하는 콜백함수), reject(기능을 수행하다가 중간에 문제가 생기면 호출하는 콜백함수)라는 두가지 콜백함수를 받는다.

  • 보통 Promise 안에선 조금 헤비한 일들을 수행한다 : 네트워크에서 데이터를 받아오거나, 파일에서 무언가 큰 데이터를 읽어오는 과정은 시간이 필요하다. 이런 것을 동기적으로 처리하게 되면 이 오래걸리는 일들을 수행하는 동안 다음라인의 일이 수행되지 않는다. 그래서 시간이 조금 걸리는 일은 프로미스를 만들어서 비동기적으로 수행해준다.

  • when new Promise os cerated, the executor runs automatically. :
    Promise는 생성과 동시에 자동적으로 executor(resolve, reject)함수 실행이 된다. 따라서 사용자가 요구했을 때만 실행하고 싶은 경우는 유의해서 작성해야한다.

  • Promise의 then, catch 체이닝은 API들을 묶어서 리턴된 값에 다음 함수를 실행하는 방식과 같다. map의 결과값에 sort 적용, sort 결과값에 join적용.

    : Promise를 만들때(const promise = new Promise((resolve, reject) => {})) 비동기적으로 수행하고 싶은 코드를 작성하고 나서, 성공적으로 잘하면 resolve 호출, 실패하면 reject 실패한 값과 왜 실패했는지 에러 전달. Promise를 이용할 때(promise.then(value => {}).catch(error=>{}).finally(()=>{}))

  • 최근에 생긴 finally : 성공, 실패 상관없이 마지막에 호출해주는 것.

Promise - resolve, reject 쓰지 않으면...


: pending 상태에서 머무르게 된다. promiese안에는 꼭!! resolve또는 reject를 이용해서 완료를 해줘야함.

Promise - resolve 호출된 경우

Promise - reject 호출된 경우

Promise 연결하기

  • .then : 값을 바로 전달할 수도 있고, 또 다른 비동기인 Promise를 전달해도 된다.

Promise chaning을 이용했을때 Error Handling

// 더 깔끔하게 쓰는 방법 
// : 콜백함수를 전달할때, 받아오는 value를 다른함수로 바로 하나를 호출하는 경우에는 생략가능.
getHen()
	.then(getEgg)
	.then(cook)
	.then(console.log);
  • 에러 처리 상황 1 의 경우 : 중간에 에러가 나서 실패해서 마지막 catch문이 리턴된다.

  • 에러 처리 상황 2 의 경우 : 중간에 에러가 나서 실패했지만, 중간에 catch문으로 에러값을 잡아주어서 다음 체인이 실행된다.


async.await

:async.await은 Promise를 감싸고 있는 Promise를 좀더 간편하게 쓸 수 있는 synthetic sugar 다. clear style of using promise ;)

  • 꼭 async,await이 좋은게 아니라 프로미스가 필요한 경우가 있다.

Promise로 썼을 때

async를 썼을때


: async라는 키워드를 함수 앞에 쓰면 코드블럭이 자동으로 Promise로 바뀐다.

await을 썼을 때

  • async 붙은 함수 안에서만 쓸 수 있다.
// getBanana()를 Promise를 이용해서 쓰면...
function getBanana(){
	return delay(3000)
    .then(()=> '바나나');
}
  • getApple() : 3초 있다가 사과호출 하는 함수.
  • getBanana() : 3초 있다가 바나나호출 하는 함수.

Promise로 결과 나타내기.

프로미스도 너무 중첩되다 보면 콜백지옥과 유사한형태가 된다.


: 6초후 출력

==> async.await을 사용해서 이렇게 간단하게 나타낼 수 있다.

: const apple = await getApple(); 3초 소요 > const banana = await getBanana(); 3초 소요
-> 총 6초가 걸려서 반환된다.

==> 병렬적으로 진행해서 3초만에 리턴값 받는 방법 : 동시다발적으로 수행하기
: 서로간의 관계가 없을때 진행가능

: Promise는 만들면 바로 실행되기 때문에 그 방법을 이용한다.

==> 병렬적으로 진행해서 리턴값 받는 방법을 깨끗하게 쓰기 : Promise.all

  • Promise.all([]) : Promise 에서 제공하는 API. 프로미스 배열을 전달하게 되면 모든 프로미스들이 병렬적으로 다 받을 때 까지 모아주는 아이.

==> 병렬적으로 진행해서 먼저 리턴되는 값 받기 : Promise.race

  • Promise.race([])

    : 사과 2초, 바나나 1초로 설정했을때 :: 바나나가 리턴된다.

Promise의 유용한 API : all, race

profile
프론트엔드 개발자

0개의 댓글