API (Application Programming Interface)


  • 어떠한 프로그램에서 제공하는 기능을 사용자가 이용할 수 있게 만들어 둔 인터페이스

  • API는 A프로그램에서 B프로그램의 기능을 활용할 수 있도록 중간에서 그 과정을 도와주는 중간 매개체




[API 간략 설명]

  • 식당의 메뉴판 = API 명세서(사용할 수 있는 기능,방법 등이 기술)
  • 메뉴를 주문 = API 요청(request) => [요청자 = Client]
  • 주문을 받고, 요리사에게 전달하는 직원 = API
  • 주문에 따라 돌려받게 되는 음식 = 응답(response)





HTTP 통신



  • API와 같이 다른 서버와 통신을 할 때는 특정한 규칙에 맞춰 그 통신이 이루어져야 함

  • HTTP = 현재 웹에서 통신을 진행할 때 가장 흔하게 사용됨

  • HTTP(Hyper Text Transfer Protocol) = 서로 다른 서버 간 문자 형식으로 데이터를 주고받을 때 지켜야 하는 규약



HTTP 통신의 단계

HTTP에서 요청을 보낼 때는 대상 서버로 HTTP 메세지를 보내고 요청 헤더(Request header)와 요청 바디(Request body)가 그 안에 담겨짐




↑ ↑ ↑

Request message

  • 이미지 가장 윗줄의 GET /data/2.5/weather? HTTP/1.1에 해당하는 부분은 start-line이라 부름

  • 사용자가 사용한 HTTP Method, 요청 URI, HTTP의 버전을 담고 있음




[Request Header]

  • 그 아래의 Host부터가 요청 헤더에 속함

  • Request header에는 요청을 받는 서버의 이름, 서버의 Version, 전달하는 컨텐츠의 Type, 요청 날짜, 요청을 보낸 컴퓨터의 정보 등 수많은 내용이 담겨짐

  • 그리고 Request header의 내용이 모두 종료되면 하나의 빈 줄로 Request body와 구분해 줌


[Request Body]

  • 사용자가 서버로 혹은 다른 사용자가 우리의 서버로 전달하고자 하는 컨텐츠를 담게 됨

  • 이 때, 어떠한 메서드를 통한 요청인지에 따라 Request body를 담을 수 있는지, 없는지가 결정 됨







Response message

  • HTTP/1.1 200 OK에 해당하는 부분은 status-line이라고 부릅니다. HTTP 버전과 상태 코드(Status code), 응답 메세지를 담고 있음



[Response header]

  • 그 아래 두번째 줄부터 Response header에 속함

  • Response header도 마찬가지로 응답 날짜, 응답을 전달한 서버의 이름, 서버의 Version, 컨텐츠의 Type 등을 담고 있음

  • Response header의 내용이 모두 종료되면 하나의 빈 줄로 Response body와 구분해 줌



[Response body]

  • Response body에는 실제로 응답 리소스 데이터가 담겨져 있음





HTTP Request 메소드

HTTP는 요청마다 메소드를 사용하며, 각각의 메소드는 그 역할이 다름





HTTP Status Code


HTTP 통신을 통해 전달하는 상태코드는 요청에 대한 응답을 세자리의 번호로 나타냄




100번대 : Information




200번대 : Success




300번대 : Redirection





400번대 : Client error




500번대 : Server error






멀티 스레드, 싱글 스레드

  • 사용자는 운영체제에게 [프로세스]라고 하는 작업 영역을 할당 받아 어떠한 동작을 수행

  • 코드의 실행, 프로그램의 실행, 파일 다운로드 등이 모두 프로세스별로 할당이 되고, 각 프로세스 내부에는 할당 받은 업무를 처리할 [스레드]가 존재






  • 멀티 스레드 = 스레드가 여러개여서 하나의 프로세스 내에서 동시에 여러개의 작업을 수행할 수 있는 작업환경을 가진 스레드







  • 싱글 스레드 = 스레드가 각 프로세스별로 하나씩만 존재하는 작업환경
    -javascript는 싱글 스레드 기반 언어로, 동기적으로 작동







동기, 비동기



동기

  • 하나의 작업이 종료될 때까지, 다음 동작을 대기시키는 실행 방식




비동기

  • 하나의 작업이 진행됨과 동시에 다른 작업도 함께 진행되는 실행방식






동기, 비동기 예시



  • 위 코드를 실행하면 "1", "3" 이 먼저 출력되고 2초 후에 "3" 이 출력됨
    (setTimeout을 건너띄고 "3" 이 먼저 출력된 것)


    *이는 [call stack][callback queue] 영역의 차이점 때문에 발생




Javascript는 동기적으로 동작

  • 자바스크립트는 [싱글 스레드] 이기 때문에 한 번에 하나의 동작만 수행 (동기적 동작)

  • 자바스크립트의 [비동기 처리]
    -특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고 그 다음 코드를 먼저 실행하는 자바스크립트의 특성

    -이런 식으로 실행 결과를 기다려주지 않는 비동기 처리의 문제로 결과값을 받기 전 다음 코드가 실행되는 문제가 발생
    *해결책 = [Callback함수, Promise 등 활용]




Call stack, Callback queue




1. Javascript 에서 기본적인 함수들은 모두 [call stack] 에 쌓이게 됨

2. 비동기 함수(Web APIs 포함)는 모두 [callback queue] 에 쌓이게 됨

3. [call stack]에 쌓인 함수들이 담긴 순서의 역순으로 우선 처리됨

4. 모든 함수가 처리되고 [call stack]이 비워지면 [callback queue]에 존재하던 비동기 함수들이 모두 [call stack] 으로 이동해서 하나씩 처리됨





Call stack, Callback queue 예시


  • 위의 코드를 실행 시, setTimeout 은 비동기 함수이기에 따로 시간을 지정하지 않아도 [callback queue] 영역으로 이동

  • [call stack]에 담긴 함수가 fun3( ),fun2( ),fun1( ) 순으로 처리된 이후, setTimeout 함수가 [call stack] 으로 옮겨져 마지막으로 실행됨







Callback 함수의 문제점

  • 자바스크립트는 싱글 스레드이기에 한 번에 하나의 동작만 수행 (동기적으로 동작)
  • 비동기 작업을 수행하기 위해 callback함수를 사용하기 시작했으나, 함수가 중첩될 수록 가독성이 떨어지게 되는 callback 지옥 이 발생

    * 이 문제에 대한 대체방안으로 나온 것이 Promise






Promise

  • Javascript 비동기 처리에 사용되는 객체

  • 현재는 얻을 수 없으나 추후 작업 완료 시 받을 수 있는 데이터에 대한 접근 수단




Promise 의 상태

  • Promise 객체는 newPromise( ) 라는 Promise 생성자를 이용해서 생성할 수 있으며, 그 상태에 따라 위의 3가지 경우(pending, fulfilled, rejected) 중 하나로 나타남



  • Promise ( ) 는 매개변수로 Callback 함수를 받음 (익명함수도 가능)
    -이 매개변수에 들어가는 함수는 Promise가 생성됨과 동시에 바로 실행됨

  • Callback 함수는 그 매개변수로 resolve, reject 두 개의 함수를 받음
    -resolve = 콜백 함수의 결과가 성공 (fulfilled 상태)
    -reject = 함수 결과가 실패 (rejected 상태)






+a) resolve, reject

  • resolve( ), reject( ) 호출

    -resolve(value) — 일이 성공적으로 끝난 경우 그 결과를 나타내는 value와 함께 호출

    -reject(error) — 에러 발생 시 에러 객체를 나타내는 error와 함께 호출


    *결과로 나타나는 value, error 는 이후 .then( ), .catch( ) 의 인자로 사용됨







  • 위 함수는 매개변수로 담은 Callback 함수 내에 setTimeout 내에 resolver( ) 를 호출함

  • 비동기 처리가 완료되면 resolver, 실패하면 reject 호출
    * resolver, reject 중 어느 하나도 호출하지 않을 시 Promise 객체 내의 상태는 pending 상태가 됨

  • 위 함수(promiseTest) 를 호출하게 되면 setTimeoutresolver 를 호출하기 전에 Promise 객체를 돌려받기에 그 상태는 Pending 상태가 됨







then( ), catch( )


  • 위의 경우처럼 비동기처리가 완료되고 결과를 반환하기 전에 코드 실행이 완료되면 그 값을 받을 수 없음

  • 통신을 이용해 외부에서 응답을 받는 과정 또한 대부분 코드 실행보다 느림 (응답을 받기 전 코드실행이 완료됨)

    ex. promise 객체로 돌려받는 응답의 상태
    -console.log(communicationResult) 를 입력하면 promise 객체를 반환 받음

    -fetch( ) 로 한 요청의 응답 결과를 아직 받지 못한 상태이기에 이 결과가 promise 객체로 반환됨

    -코드 실행보다 통신의 응답을 받는 것이 느리기 때문에 이런 문제가 발생
    * 이 때 then( ), catch( ) 를 이용해서 결과를 바로 받을 수 있음





then( )

  • 요청 실행 후 그 응답으로 promise 객체를 반환할 때 끝에 .then( ) 을 붙여서 사용하면 응답의 결과를 바로 받을 수 있음
    *promise 객체를 반환하는 함수라면 모두 .then( ) 사용가능




  • then( ) 은 그 매개변수로 함수를 받을 수 있고, 해당 함수의 매개변수로 응답에 대한 결과 (res), 즉 반환되는 데이터를 받을 수 있음

  • then( ) 을 이용해 요청에 대한 응답 결과를 바로 받고, 이를 then( ) 내부 함수의 인자로 받아와서 활용
    *[결과를 바로 받는 것] => 정확히는 요청에 대한 응답을 기다려서 그 결과를 받았을 때 이 값을 then( ) 내부에 바로 할당해 주는 것





catch( )

  • 통신에 문제가 생기거나 에러가 발생할 경우, catch( ) 를 이용해서 그 분기를 나눠줄 수 있음

  • 위와 같이 .then( ) 뒤에 붙여서 사용가능, catch( ) 또한 매개변수로 함수를 받을 수 있으며 해당 함수의 매개변수로 에러의 내용을 받을 수 있음








구조분해할당

구조화 되어 있는 배열, 객체 같은 데이터를 destructuring(분해)시켜, 각각의 변수에 재할당하는 것


  • 배열의 경우 순서에 따라 변수에 데이터가 재할당 됨
    *one = arr[0]의 데이터, two = arr[1]의 데이터...








  • 객체의 경우 재할당하는 변수명을 객체 내의 Key로 입력하며, 이 때 해당하는 Key의 Value가 그 데이터로 할당됨
    *name = obj.name, gender = obj.gender





+a) 객체 구조분해할당 시 변수명 따로 지정하기







값의 복사




spread 연산자

  • 배열, 객체 등 반복가능한 값들의 집합을 개별요소로 분리시키는 것

  • 선언된 배열의 이름 앞에 ...을 붙여서 사용 가능






얕은 복사

spread 연산자를 활용해서 배열, 객체의 복사 가능 (얕은복사)

[BUT] 객체의 경우, 객체 내의 객체는 복사가 되지 않고 그 값이 변경될 경우 복사본에도 똑같이 적용됨




얕은복사와 Heap

  • Heap = 참조타입의 데이터가 담기는 임시저장 메모리

  • Heap 영역은 참조타입 데이터처럼 그 크기가 유동적으로 변할 수 있음




  • 객체를 spread 연산자로 복사할 경우 기존 주소와의 연결을 끊고, 새로운 주소를 할당받아 복사가 되었지만 객체 내의 객체(Heap 영역)는 spread 의 영향으로 분리되지 않아 똑같은 주소를 가지고 있게 됨 *(복사본 데이터 변경에 원본도 영향 받음)







깊은 복사

JSON.stringify( ), JSON.parse 를 사용해서 얕은 복사의 문제점 해결 가능


JSON.stringify( ) => ( ) 안의 값을 JSON 데이터 포맷으로 변환
JSON.parse( ) => ( ) 안의 값을 기존의 데이터 형태로 다시 변환


  • JSON 형태로 변환시 문자열이 되기 때문에 완전히 새로운 주소값을 가지게 됨

  • 이후 다시 기존의 데이터 형태로 변환하면 새로운 객체가 생성되어 deepCopy에 담기는 것임으로 원본 객체의 주소와 완전히 다른 새로운 복사가 됨








Rest Parameter

  • 배열, 객체, 함수의 매개변수에 사용 가능
    *spread 와 달리 그 결과를 [배열] 형태로 반환

  • ...rest 로 사용 가능하며 꼭 rest 로 작성할 필요는 없음 (매개변수처럼 이름 지정 가능)

  • rest 는 꼭 값들 중 마지막에 작성되야 함
    ex. [one, two, ...rest]






객체에서의 rest parameter

  • 구조분해할당 방식으로 사용 가능

  • [name]이란 key와 그 value를 제외한 나머지가 객체 형태로 rest에 담김







배열에서의 rest parameter

  • 배열 또한 구조분해할당 방식으로 사용

  • number[0], number[1] 을 제외한 나머지 데이터가 rest에 담김







함수 매개변수에서의 rest parameter

  • 함수의 경우 받게 되는 그 매개변수에 rest를 적용가능

  • 위와 같이 매개변수에 ...rest 를 넣어주면, 매개변수가 몇 개가 되는지 모를경우 rest로 그 매개변수를 다 담을 수 있음
profile
막 발걸음을 뗀 신입

0개의 댓글