Node.js 모듈 사용 / Fetch 네트워크 요청

[JS/Node] 비동기 2


Node.js 모듈 사용법

브라우저에서 사용할 수 있는 비동기 흐름은 타이머 혹은 DOM 이벤트와 관련된 상황으로 다소 한정적.

BUT!

Node.js의 경우 많은 API가 비동기로 작성됨.

Node.js ?

로컬 환경에서 자바스크립트를 실행할 수 있는 자바스크립트 런타임이다. 브라우저에서 불가능한 기능이 가능.

모듈 ? 어떤 기능을 조립할 수 있는 형태로 만든 부분. fs(File System) 모듈은 PC의 파일을 읽거나 저장하는 일을 지원함.

서버사이트 스크립트 언어가 아닌 프로그램(환경)이다.

웹서버와 같이 확장성 있는 네트워크 프로그램 제작을 위해 만들어졌다. ⇒ 한가지 언어로 전체 웹 페이지를 만들 수 있게 됨.

Node.js의 특징

  • 자바스크립트 언어 사용
  • 자바스크립트 엔진 사용으로 속도가 빠르다
  • 이벤트 기반 비동기 방식(Non-Blocking)
    • Node.js 에서 모든 API가 비동기 방식이므로, 호출 후 응답을 기다리지 않고 다른 API를 호출. 이전에 호출한 API의 응답이 오면 이벤트 루프가 확인하여 처리함.
    • 이벤트 루프(event loop)는 여러 이벤트가 동시 발생했을 때 어떤 순서로 콜백함수를 호출할지 판단.
    • 비동기란 이전 작업이 완료될 때까지 대기하지 않고 동시에 작업을 수행하는 것.
  • 단일 스레드
    • 스레드 : 프로세스 내에서 실행되는 흐름의 단위. 프로세스는 스레드를 여러 개 생성하여 여러 작업을 동시에 처리. 스레드들은 부모 프로세스의 자원을 공유. 같은 주소의 메모리에 접근 가능하여 데이터 공유할 수 있다.
    • 프로세스 : 운영체제에서 할당하는 작업의 단위. 노드나 웹 브라우저 등의 프로그램은 개별적인 프로세스. 프로세스 간 메모리 자원 공유 x.
    • 복잡한 비동기 I/O 응용 프로그램을 싱글 스레드 자바스크립트로 작성하여 결과물 실행 속도와 개발 편의성이 좋음. 그러나 CPU의 높은 연산력을 요구하는 프로그램을 짜면 성능이 좋지 않음.

Node.js 내장 모듈 사용 방법

[Node.js 내장 모듈 목록]

  • DNS 모듈 사용법 :

DNS | Node.js v18.2.0 Documentation

  • 파일 시스템 모듈 → 파일을 읽거나 저장하는 기능을 구현하도록 돕는 메소드
  • 파일 읽을 때 적합한 메소드 → readFile
  • 파일 저장할 때 적합한 메소드 → writeFile

모듈을 사용하기 위해 불러오는 과정

Node.js 에서 다른 파일을 불러오기 위한 require 구문

1
2
3
4
5
6
// 자바스크립트 코드 가장 상단에 require 구문 이용

const fs = require('fs'); // 파일 시스템 모듈 불러오기
const dns = require('dns'); // DNS 모듈 불러오기

// fs.readFile 메소드 등을 사용할 수 있음

3rd-party 모듈 사용하는 방법

**써드 파티 모듈(3rd-party module)**은 해당 프로그래밍 언어에서 공식적으로 제공하는 빌트인 모듈이 아닌 모든 외부 모듈을 말한다.

ex) Node.js에서 underscore는 Node.js 공식문서에 없는 모듈이기 때문에 써드 파티 모듈이라고 할 수 있음.

써드 파티 모듈을 다운 받기 위해 터미널에서 npm을 사용해야 함

[ 터미널에서 underscore 모듈 설치하기 ]

1
npm install underscore

⇒ node_modules에 underscore 설치한 후,

Node.js 내장 모듈을 사용하듯 require 구문을 사용해 underscore을 사용할 수 있음

1
2
3
const _ = require('underscore');

// Node.js의 3rd-party 모듈인 'underscore'사용

fs.readFile(path, [options], callback)

메소드 fs.readFile은 비동기적으로 파일 내용 전체를 읽는다. 로컬에 존재하는 파일을 읽어온다. 이 메소드는 실행할 때 인자 세 개를 넘길 수 있다.

  • path → <string>, <Buffer>, <URL>, <integer>
    • path 에는 파일 이름을 인자로 넘길 수 있다. 위의 네가지 종류 타입을 넘길 수 있지만 일반적으로는 문자열 타입으로 넘김
1
2
3
// /ect/passwd 파일을 불러오는 예제

fs.readFile('/etc/passwd', ..., ...)
  • options → <Object>, <string>
    • 대괄호로 감싼 두번째 인자 options는 선택적으로 넣거나 생략할 수 있는 인자.
    • 객체 형태 또는 문자열 타입으로 넘길 수 있다. 문자열의 경우 인코딩을 넘긴다.
1
2
3
4
5
6
7
let options = {
encoding: 'utf8' // UTF-8 인코딩 방식으로 열기
flag: 'r' // 읽기 위해 열기
}

// 옵션을 사용하여 passwd 파일을 읽는다
fs.readFile('/etc/passwd', options, ...)
  • callback → <Function>
    • err → \
    • data → <string> , <Buffer>
      • 콜백 함수를 전달한다. 파일을 읽은 후에 비동기적으로 실행되는 함수.
      • 두 가지 파라미터가 존재한다. 에러가 발생하지 않으면 err ⇒ null 이 되고, data 에 문자열이너 Buffer 라는 객체가 전달된다. (data는 파일의 내용)
1
2
3
4
5
6
7
8
// fs.readeFile 메소드로 파일의 데이터를 읽어 들인다

fs.readFile('test.txt', 'utf8', (err, data) => {
if (err) {
throw err; // 에러를 던짐
}
console.log(data);
});

fetch를 이용한 네트워크 요청

비동기 요청의 가장 대표적인 사례는 네트워크 요청이다. 네트워크를 통해 이뤄지는 요청은 형태가 다양하며 URL로 요청하는 경우가 가장 흔함.

URL 요청을 가능하게 해주는 API가 fetch API이다.

포털사이트는 변하는 정보고정적인 정보가 따로 분리된 구성이다. 최신 뉴스나 날씨 정보 등 동적으로 데이터를 받아와야 하는 정보는 해당 정보만 업데이트하기 위해 요청 API를 이용한다. 그 중 대표적인 fetch API를 이용해 해당 정보를 원격 URL로부터 불러오는 경우, 원격 URL로부터 정보를 받아와서 DOM 엘리먼트를 업데이트 한다.

URL에 요청을 보내고 필요한 정보를 받아온다.

fetch API는 특정 URL로부터 정보를 받아오는 역할을 하는데, 이 과정이 비동기로 이루어져 다소 시간이 걸릴 수 있다. 시간이 소요되는 작업을 요구할 경우에는 blocking이 발생하면 안되므로 DOM에 정보가 표시될 때 까지 로딩 창을 대신 띄우는 경우도 있다.

fetch API 사용법

1
2
3
4
5
6
7
8
// fetch API는 Promise의 형식으로 이루어져 있음

let url = "---주소---";

fetch(url)
.then((response) => response.json()) // 자체적으로 json() 메소드가 있어, 응답을 JSON 형태로 변환시킨 후 다음 Promise로 전달
.then((json) => console.log(json)) // 콘솔에 json을 출력
.catch((error) => console.log(error)); // 에러가 발생한 경우, 에러를 띄운다

→ 자세한 내용 : MDN 참고