
package.json파일에 위와 같이 scripts 를 추가해주면 npm start 할때 node index.js가 실행되고 npm dev를 쓰면 nodemon index.js가 실행된다.
JavaScript가 싱글 스레드이므로 Node.js 또한 싱글 스레드이다. 예를 들어 우리가 새로운 파일을 만들면 각각의 파일이 바로 스레드가 되는 것이다. 여기서 싱글 스레드란 한 번에 하나의 일밖에 하지 못한다는 것을 뜻한다.
node.js가 우리가 보이지 않는 곳에서 작동되는 순서는 아래와 같다.
이벤트 루프 내에서 처리가 오래 걸리는 무거운 데이터를 다룰 때 스레드풀이 존재한다. 스레드풀은 여러개의 작접을 동시에 처리하기 위해 미리 생성된 스레드들의 모음으로, node.js에서 시간이 많이 걸리는 작업은 스레드풀을 사용해 비동기적으로 실행된다.이벤트 루프는 스레드풀과 연동하여, 특정 시점에 어떤 작업을 수행할지 스레드를 스케줄링 하는것이다.
따라서 JavaScript처럼 Node.js도 콜백을 통해 비동기 처리를 설정할 수 있다. 먼저 콜백이 없을 때의 코드는 다음과 같다.
import fs from 'fs'
console.log('start')
let data = fs.readFileSync('test.txt')
console.log(data.toString());
console.log("end")
이 코드는 순서대로 start, data.toString(), end 순서대로 출력된다. readFileSync()를 쓴 이유는 동기적으로 파일을 불러오기 때문이다.
다음으로 콜백을 사용했을 때의 코드를 보자.
import fs from 'fs'
console.log('start')
fs.readFile('test.txt', 'utf-8', (err,res) => {
err? console.log(err) : console.log(res)
})
console.log("end")
파일을 읽어올 때 비동기로 사용할 수 있는 readFile()을 사용했다. 여기서는 비동기로 코드가 실행되므로 결과값이 start, end, 그리고 파일 내용 순으로 출력된다.
Node.js에서 Events를 실행하는 방법을 알아보자.
import EventEmitter from 'events'
// creating instance
const customEmitter = new EventEmitter()
//1. on: listen/register for an event
//2. once: listen/register for an event. it fires only once
//3. emit: emit/call an event
customEmitter.on('response', (name,id) => {
console.log(`user: ${name} id: ${id}`)
})
customEmitter.emit('response', "john", 18);
customEmitter.emit('response', "Yukka", 28);
customEmitter.emit('response', "Zzong", 11);
customEmitter.once('response', (name,id) => {
console.log(`user: ${name} id: ${id}`)
})
customEmitter.emit('response', "john", 18);
customEmitter.emit('response', "Yukka", 28);
customEmitter.emit('response', "Zzong", 11);
Node.js에서 events를 실행할 때는 항상 인스턴스를 만들어줘야 한다. once는 이벤트를 딱 한 번만 실행할 때 사용하고, on은 여러 번 실행할 때 사용한다. emit은 JavaScript에서 함수를 호출하는 것처럼 이벤트를 호출할 때 사용한다. 위의 코드처럼 첫 번째 인자는 'response'를 써주고, name과 id 매개변수를 받아야 하므로 emit에서 매개변수에 들어갈 인자를 써준다.
streams는 엄청 큰 데이터를 가지고 올 때 쓰인다. 예를들어 data.js에 이렇게 큰 파일이 있으면
import fs from 'fs'
for(let i=0; i < 10000; i++){
fs.writeFileSync('./data.txt', `${i}\n`,{flag:"a"})
}
index.js에서 이 파일을 불러올 때 streams를 이용할 수 있다.
import { createReadStream } from "fs";
// const stream = createReadStream('./data.txt', {highWaterMark: 90000})//control the size of the buffer
const stream = createReadStream('./data.txt', {encoding: 'utf8'})
stream.on('data', (data) => console.log(data))