url 모듈 안에 URL 생성자가 존재함. 생성자 안에 주소를 넣어 객체로 만들면 주소가 부분별로 정리됨.
출력결과
이 중 origin, username, password,searchParams속성은 WHATWG에만 있는 속성
searchParams: search URL.searchParams.getAll(키): 키에 해당하는 모든 값 URL.searchParams.get(키): 키에 해당하는 첫 번째 값만 URL.searchParams.has(키): 해당 키 존재 여부(true, false) URL.searchParams.keys(): searchParams의 모든 키를 반복(ES2015 문법) 객체로 가져옴 URL.searchParams.values(): searchParams의 모든 값을 반복기 객체로 가져옴 URL.searchParams.append(키, 값): 해당 키를 추가. (같은 키의 값이 있다면 유지하고 하나 더 추가) URL.searchParams.set(키, 값): 같은 키의 값들을 모두 지우고 새로 추가 URL.searchParams.delete(키): 해당 키 제거 URL.searchParams.toString(): 조작한 searchParams를 다시 문자열 형태 저장. 이 문자열을 search 속성에 대입하면 주소 객체에 반영됨.
new Worker(__filename): 현재 파일(__filename)에서 워커 스레드 실행
worker.postMessage(메시지): 워커에 데이터 전송
parentPort.on('message'): 부모로부터 메시지 받음
parentPort.postMessage(메시지): 부모에 메시지 전송
parentPort.close(): 워커에서 on메서드 사용할 때는 직접 워커를 종료해야 함. 부모와의 연결 종료. worker.on('exit') 실행
worker.on('message'): 워커로부터 메시지 받음
worker_data.js
new Worker(__filename, {workerData: {start: 1}, }): new Worker 호출. 두 번째 인수의 workerData 속성으로 원하는 데이터 전송 가능.
prime.js(워커 스레드 없이)
const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');
const min = 2;
let primes = []; //소수 배열
function findPrimes(start, range) { //소수 검사
let isPrime = true;
const end = start + range;
for (let i = start; i < end; i++) {
for (let j = min; j < Math.sqrt(end); j++) {
if (i !== j && i % j === 0) {
isPrime = false;
break;
}
}
if (isPrime) {
primes.push(i);
}
isPrime = true;
}
}
if (isMainThread) {
const max = 10000000;
const threadCount = 8; //워커 스레드 개수
const threads = new Set(); //워커 스레드 집합
const range = Math.ceil((max - min) / threadCount);
let start = min;
console.time('prime'); //시간 측정 시작
for (let i = 0; i < threadCount - 1; i++) { //워커 스레드에 수 분배
const wStart = start;
threads.add(new Worker(__filename, { workerData: { start: wStart, range } }));
start += range;
}
threads.add(new Worker(__filename, { workerData: { start, range: range + ((max - min + 1) % threadCount) } }));
for (let worker of threads) { //스레드 집합에 있는 모든 워커에 대해서
worker.on('error', (err) => { //에러 발생 시
throw err;
});
worker.on('exit', () => { //워커 종료 시
threads.delete(worker); //해당 워커 삭제
if (threads.size === 0) { //남은 워커가 없는 경우
console.timeEnd('prime'); //시간 측정 종료
console.log(primes.length); //배열에 저장된 소수의 개수 출력
}
});
worker.on('message', (msg) => { //워커에게서 데이터(소수) 수신 시
primes = primes.concat(msg); //소수 배열에 해당 데이터 추가
});
}
} else { //워커 스레드 코드
findPrimes(workerData.start, workerData.range); //워커스레드 소수 검사 실행
parentPort.postMessage(primes); //부모(메인) 스레드에 소수 데이터 전송
}
prime.js(워커 스레드X)와 prime_worker.js(워크스레드O) 소요 시간 비교
스레드를 생성하고 스레드 사이에서 통신하는 데 상당한 비용 발생->이를 고려하여 멀티 스레딩 해야 함!!
(8) child_process
다른 프로그램을 실행하거나 명령어를 수행하고 싶은 경우 사용하는 모듈 다른 언어의 코드를 실행하고 결괏값을 받을 수 있음 현재 노드 프로세스 외에 시로운 프로세스를 띄워서 명령을 수행하고 노드 프로세스에 결과를 알려줌
exec.js
exec(명령어): 위 코드에선 dir명령(현재 폴더의 파일 목록 출력) +)리눅스나 맥의 경우 'ls'
stdout: 표준 출력, data이벤트 리스너에 버퍼 형태로 전달
stderr: 표준 에러, data이벤트 리스너에 버퍼 형태로 전달
spawn.js(파이썬 프로그램 실행)
spawn(명령어, 옵션배열)
(9) 기타 모듈들
assert: 값을 비교하여 프로그램이 제대로 동작하는지 테스트하는 데 사용
dns: 도메인 이름에 대한 IP주소를 얻어내는 데 사용
net: HTTP보다 로우 레벨인 TCP나 IPC 통신을 할 때 사용
string_decoder: 버퍼 데이터를 문자열로 바꾸는 데 사용
tls: TLS와 SSL 관련된 작업을 할 때 사용
tty: 터미널과 관련된 작업을 할 때 사용
dgram: UDP 관련 작업을 할 때 사용
v8: V8 엔진에 직접 접근할 때 사용
vm: 가상 머신에 직접 접근할 때 사용
6. 파일 시스템 접근하기
fs 모듈 파일 시스템에 접근하는 모듈 파일 생성, 삭제, 읽기, 쓰기 폴더 생성, 삭제
readFile.js
fs.readFile(파일 경로, 콜백함수): 읽을 파일 경로 지정, 콜백형식의 모듈. 결과물을 buffer형태로 출력하므로 data에 toString()을 붙여러 출력.
readFilePromise.js
.promises: 프로미스 기반의 fs 모듈 사용 가능
writeFile.js
fs.writeFile(파일 경로, 내용, 콜백함수)
(1) 동기 메서드와 비동기 메서드
노드는 대부분의 메서드를 비동기 방식으로 처리 fs모듈은 동기와 비동기 메서드 모두 존재
async.jsasync.js 출력결과
비동기: 백그라운드에 해당 파일을 읽으라고만 요청한 후 다음 작업으로 넘어감. 위 코드의 경우, 파일 읽기 요청만 세 번 보내고 console.log('끝') 실행, 파일 읽기가 완료되면 백그라운드가 다시 메인 스레드에 알리고 난 후 콜백함수 실행.
동기/비동기:백그라운드 작업 완료 확인 여부 블로킹/논 블로킹:함수가 바로 return 되는지 여부
동기-블로킹: 백그라운드 작업 완료 여부 계속 확인, 호출한 함수 바로 return 되지 않고 백그라운드 작업 끝나야 return 비동기-논블로킹:호출된 함수 바로 return 되어 다음 작업으로 넘어가며, 백그라운드 작업 완료 여부는 신경 쓰지 않고 나중에 백그라운드가 알림을 줄 때 처리
sync.js
동기: 순서대로 실행. 백그라운드가 작업하는 동안 메인 스레드는 대기->비효율적. 초기화 용도 사용 권장.