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'): 워커로부터 메시지 받음
new Worker(__filename, {workerData: {start: 1}, }): new Worker 호출. 두 번째 인수의 workerData 속성으로 원하는 데이터 전송 가능.
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); //부모(메인) 스레드에 소수 데이터 전송
}
스레드를 생성하고 스레드 사이에서 통신하는 데 상당한 비용 발생->이를 고려하여 멀티 스레딩 해야 함!!
(8) child_process
다른 프로그램을 실행하거나 명령어를 수행하고 싶은 경우 사용하는 모듈 다른 언어의 코드를 실행하고 결괏값을 받을 수 있음 현재 노드 프로세스 외에 시로운 프로세스를 띄워서 명령을 수행하고 노드 프로세스에 결과를 알려줌
exec(명령어): 위 코드에선 dir명령(현재 폴더의 파일 목록 출력) +)리눅스나 맥의 경우 'ls'
stdout: 표준 출력, data이벤트 리스너에 버퍼 형태로 전달
stderr: 표준 에러, data이벤트 리스너에 버퍼 형태로 전달
spawn(명령어, 옵션배열)
(9) 기타 모듈들
assert: 값을 비교하여 프로그램이 제대로 동작하는지 테스트하는 데 사용
dns: 도메인 이름에 대한 IP주소를 얻어내는 데 사용
net: HTTP보다 로우 레벨인 TCP나 IPC 통신을 할 때 사용
string_decoder: 버퍼 데이터를 문자열로 바꾸는 데 사용
tls: TLS와 SSL 관련된 작업을 할 때 사용
tty: 터미널과 관련된 작업을 할 때 사용
dgram: UDP 관련 작업을 할 때 사용
v8: V8 엔진에 직접 접근할 때 사용
vm: 가상 머신에 직접 접근할 때 사용
6. 파일 시스템 접근하기
fs 모듈 파일 시스템에 접근하는 모듈 파일 생성, 삭제, 읽기, 쓰기 폴더 생성, 삭제
fs.readFile(파일 경로, 콜백함수): 읽을 파일 경로 지정, 콜백형식의 모듈. 결과물을 buffer형태로 출력하므로 data에 toString()을 붙여러 출력.
.promises: 프로미스 기반의 fs 모듈 사용 가능
fs.writeFile(파일 경로, 내용, 콜백함수)
(1) 동기 메서드와 비동기 메서드
노드는 대부분의 메서드를 비동기 방식으로 처리 fs모듈은 동기와 비동기 메서드 모두 존재
비동기: 백그라운드에 해당 파일을 읽으라고만 요청한 후 다음 작업으로 넘어감. 위 코드의 경우, 파일 읽기 요청만 세 번 보내고 console.log('끝') 실행, 파일 읽기가 완료되면 백그라운드가 다시 메인 스레드에 알리고 난 후 콜백함수 실행.
동기/비동기:백그라운드 작업 완료 확인 여부 블로킹/논 블로킹:함수가 바로 return 되는지 여부
동기-블로킹: 백그라운드 작업 완료 여부 계속 확인, 호출한 함수 바로 return 되지 않고 백그라운드 작업 끝나야 return 비동기-논블로킹:호출된 함수 바로 return 되어 다음 작업으로 넘어가며, 백그라운드 작업 완료 여부는 신경 쓰지 않고 나중에 백그라운드가 알림을 줄 때 처리
동기: 순서대로 실행. 백그라운드가 작업하는 동안 메인 스레드는 대기->비효율적. 초기화 용도 사용 권장.