S2 Unit3 - [JS/Node] 비동기 1

딩쓰·2022년 9월 26일

코드스테이츠 TIL

목록 보기
3/19
post-thumbnail

Chapter2. 비동기

  • Blocking: 하나의 작업이 끝날 때까지, 이어지는 작업을 “막는 것”

  • 동기적(synchronous): 새로운 작업 시작 지점과 이전 작업 완료 시점이 같은 상황
    ex): 카페에서 첫번째로 주문한 커피가 나오고 나서야 두번째로 커피를 주문할 수 있는것

  • Node.Js 개발자는 Node.js를 non-blocking하고 비동기적으로 작동하는 런타임으로 개발함

  • JavaScript에서 특히 비동기적 실행이라는 개념은 웹 개발에서 유용한데, 아래같은 작업들은 비동기적으로 작동되어야 효율적이기 때문

    • 백그라운드 실행, 로딩 창 등의 작업
    • 인터넷에서 서버로 요청을 보내고, 응답을 기다리는 작업
    • 큰 용량의 파일을 로딩하는 작업

Chapter2-1. 비동기 호출

비동기의 주요 사례

  • DOM Element의 이벤트 핸들러
    • 마우스, 키보드 입력 (click, keydown 등) ➡️ DOM 세션
    • 페이지 로딩 (DOMContentLoaded 등) ➡️ DOM 런코 Note
  • 타이머
    • 타이머API(setTimeOut,clearTimeout,setInterval,clearInterval)
      ➡️ Timer API 세션
    • 애니메이션 API (requestAnimationFrame) ➡️ 예시 넣기
  • 서버에 자원 요청 및 응답
    • fetch API ➡️ 서버에 요청하기 세션
    • AJAX (XHR) ➡️ 비동기 자바스크립트와 XML을 말함. 서버와 통신하기 위해 XMLHttpRequest 객체를 사용하고 JSON, XML, HTML 그리고 일반 텍스트 형식 등을 포함한 다양한 포맷을 주고 받을 수 있음

Chapter2-2. 비동기 JavaScript

클라이언트:”서버로 접속하는 컴퓨터” -> 보통 우리들의 컴퓨터
서버: "무언가(서비스,리소스 따위)를 제공하는 컴퓨터" -> 웹 서버, 게임 서버 등

Chapter2-3. Callback

비동기의 문제점 해결하는 방법

  • 비동기 처리는 특정 코드의 실행이 완료될 때까지 기다리지 않고 다음 코드를 수행하기 때문에 클라이언트가 서버에 데이터를 요청했을 때 그 데이터가 도착하기도 전에 화면에 출력하는 코드가 실행되어 화면에 데이터가 출력되지 않는 문제가 생긴다.
    그래서 순서를 제어하고 싶을 때 아래와 같은 방법을 사용할 수 있음
  1. 콜백함수 예시
const printString = (string, callback) => {
    setTimeout(
      () => {
        console.log(string)
        callback()
      },
      Math.floor(Math.random() * 100) + 1
    )
}

const printAll = () => {
  printString("A", () => {
    printString("B", () => {
      printString("c", () => {})
    })
  })
}  
printAll()  // A,B,C 가 순서대로 출력됨 (순서가 안바뀜)
  

콜백함수의 문제점: 아래처럼 콜백함수 헬이 일어날 수 있음 -> promise 사용이 필요

Chapter2-4. Promise, async/await

프로미스(Promise)

1.프로미스의 3가지 상태(states)

  • 여기서 말하는 상태란 promise의 처리 과정을 의미. new Promise()로 promise를 생성하고 종료될 때까지 아래와 같은 상태를 갖는다.

1.Pending(대기) : 이행하지도 실패하지도 않은 상태로 비동기 처리가 아직 완료되지 않은 상태
2.Fulfilled(이행) : 비동기 처리가 완료되어 promise가 결과 값을 반환해준 상태
3.Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태

new Promise(); //new Promise() 메서드를 호출 ->Pending(대기) 상태

new Promise(function(resolve, reject) {
  // ...
}); //new Promise() 메서드를 호출할 때 콜백 함수를 선언가능, 콜백 함수의 인자는 resolve, reject 

new Promise(function(resolve, reject) {
  resolve();
}); // resolve를 호출 ->  Fulfilled(이행) 상태

new Promise(function(resolve, reject) {
  reject();
}); // reject를 호출 ->  Rejected(실패) 상태
  • 콜백 지옥을 해결하기 위해 promise 사용할 수 있음
const printString = (string) => {
  return new Promise((resolve, reject) => {
    setTimeout(
     () => {
      console.log(string)
      resolve()
     },
     Math.floor(Math.random() * 100) + 1
    )
  }) 
}

const printAll = () => {
  printString("A")
   .then(() => {
     return printString("B")
      printString("c", () => {})
   })
   .then(() => {
     return printString("c")
  })
}  
printAll() 
  • 리턴 차리를 잘 해주지 않으면, 아래와 같이 프로미스 지옥이 일어날 수 있음
function gotoCodestates(){
  return new Promise((resolve, reject) => {
    setTimeout (()=>{resolve('1. go to codestates ')}, 100)
  })
}
function sitAndCode(){
  return new Promise((resolve, reject) => {
    setTimeout (()=>{resolve('2. sit and code')}, 100)
  })
}
function eatLunch(){
  return new Promise((resolve, reject) => {
    setTimeout (()=>{resolve('3. eat lunch')}, 100)
  })
}
function goToBed(){
  return new Promise((resolve, reject) => {
    setTimeout (()=>{resolve('4. go to bed')}, 100)
  })
}

gotoCodestates()
.then(date => {
  console.log(data)
  
  sitAndCode()
  .then(data => {
    console.log(data)
    
    eatLunch()
    .then(data => {
      console.log(data)
      
      goToBed()
      .then(data => {
        console.log(data)
      })
    })
    
  })
  
})
  • 아래와 같이 Promise Chaining 으로 고칠 수 있음 (깔끔함을 유지)
gotoCodestates()
.then(date => {
	console.log(data)
  	return sitAndCode()
})  
.then(data => {
    console.log(data)
  	return eatLunch()
})
.then(data => {
	console.log(data)
	return goToBed()
})
.then(data => {
	console.log(data)
})

async/await

  • 프로미스인데 실제로 보이는 모습이 다른것.
  • 프로미스와 동일하게 돌아가는데 표현을 동기적으로 쓸 수 있어서 코드 가독성을 높임
  • async와 await를 사용해 비동기들을 동기적 프로그램처럼 사용할 수 있음 (일반함수 처럼 순차적 실행)
function gotoCodestates(){
  return new Promise((resolve, reject) => {
    setTimeout (()=>{resolve('1. go to codestates ')}, 100)
  })
}
function sitAndCode(){
  return new Promise((resolve, reject) => {
    setTimeout (()=>{resolve('2. sit and code')}, 100)
  })
}
function eatLunch(){
  return new Promise((resolve, reject) => {
    setTimeout (()=>{resolve('3. eat lunch')}, 100)
  })
}
function goToBed(){
  return new Promise((resolve, reject) => {
    setTimeout (()=>{resolve('4. go to bed')}, 100)
  })
}

const result = async () => {
  const one = await gotoCodestates();
  console.log(one)
  
  const two = await sitAndCode();
  console.log(two)
  
  const three = await eatLunch();
  console.log(three)
  
  const four = await goToBed();
  console.log(four)
}

result();
```)



 
profile
Frontend Developer

0개의 댓글