생각기록

2022-11-17 node.js 모듈, 구조 분해 할당, callback 본문

SeSAC 풀스택/Nodejs

2022-11-17 node.js 모듈, 구조 분해 할당, callback

끼록관 2022. 11. 17. 17:23

모듈(Module)

관련된 객체들의 집합소

특정한 기능을 하는 함수나 변수들을 집합

재사용 가능한 코드 조각

 

장점

  • 코드 추상화G
  • 코드 캡슐화(반복적 x, 묶어서 사용)
  • 코드 재사용
  • 의존성 관리

ex)변수 master 명칭을 여기저기서 쓰고있다.

관리자를 이름 바꾸고 싶을때, 마스터를 전체 검색해서 하나 하나 지워야하는데, 어느 한곳에 관리자는 마스터 라고 해놓고 호출해서 썼다면, 그곳에서 바꾸면되기때문에 독립적이고 유지보수하기 좋다. 

 

모듈 만드는 방법

모듈화

module.exports는

  • 메소드를 붙여 사용한다
  • 함수
  • 직접 만든 객체
  • module.exports는 1개의 값만 할당 할 수 있다.
  • 그래서 객체를 사용하여 복수의 기능을 하나로 묶어 사용하는 방식을 사용한다.
  • 모듈화 하겠다 = 다른 파일 (밖)에서  변수, 함수, 객체를 사용할 수 있게 함 require과 짝꿍

 

require()는

module.exports를 리턴, 즉 호출하는 함수이다.

module.exports = A ;
const B = require('위의 module 파일');

여기서
A = B
만약 A가 10이면, B도 10이다.
만약 A가 { a: 1, b: 2}면, B도 { a: 1, b: 2}라는 배열을 이다.

 

module.exports  =  A ;

 

module.exports = { A } ;

A가  {  }로 객체이며, 키:값 형태

반환받는 require()함수도  { } 형태로 받는다.

//2022_11_17_모듈1.js 파일
const a = 1;
const b = 3;

const array = {
    a : a,
    b : b
};
module.exports = array;

//2022_11_17_모듈2.js 파일
// {a: 1, b:3}
const { a, b } = require('./01-module.js');


function add(){
    return a + b;
}

module.exports = add;
// module.exports = { add };
// result = { add : function(){return a + b } }
// result.add();

//2022_11_17_모듈3.js 파일
const result = require('./01-module2.js');
// result = function(){return a + b;}
console.log( result );
console.log( result() );
// { add : Function } 이 형태로 넘어왔을 때는
// console.log( result.add() );

 

 

간단히 모듈파일 만들고 사용해보기

  • js파일 2개 만들기
  • 밖으로 보내줄 exports  파일과
  • 받아낼 require 파일을 만든다.

첫번째 파일 변수 a, b와, test함수를 객체 exports에 담음 

두번째 파일에서 require 함수로 위의 모듈을 result란 객체에 넣는다.

첫번째 exports가 { } 로 되어있어서

require함수도 { } 로 감싸서 값을 반환합니다.

  • a : 'a변수'
  • b : 'b변수'
  • test : [function: test] 

키 : 값 형태로  배열처럼 구성되어있다.

함수 test는 함수이름 : 값 으로 반환된다

 

module.exports = add ; 로 { } 가 없으면, 값만 출력된다.

접은글 참고

더보기

만약 중괄호가 없다면?

 

불러올때는 배열 호출하듯 하면 된다.

 

변수와 함수 호출은 좀 다르다.

result.a // result라는 객체의 a라는 이름표를 가져와

result.test() // 함수는 result라는 객체 속에 test()라는 함수를 실행 해줘

 

터미널로 확인하는 법!

crtl + shift  + 물결 > 터미널 실행 명령어

터미널을 키고, 현재 이파일이 있는 폴더로 옮겨옵니다. (cd 명령어 사용)

 

파일 찾는 tip

터미널 이전명령어 화살표(위) 방금명령어가 복사 붙이기 되어 나온다.

node 치고  tab 치면, 저 이름으로 시작하는 파일이나 폴더를 자동완성 시켜줍니다.

 


node의 내장 객체

노드제이에스를 설치하면, 로컬에 깔린 객체들

js의 date객체같은 것

 

global 내장객체

  • 노드의 전역 객체 (*전역: 어디서든)
  • 모든 파일에서 접근 가능
  • 생략하여 사용 가능

터미널에 보면 이런식으로 출력된다.

PS C:\Users\SBAUser\Desktop\github\SeSAC_1YS_Web\HTML\node> node '.\2022_11_17_내장객체.js'
<ref *1> Object [global] {
  global: [Circular *1],
  clearInterval: [Function: clearInterval],
  clearTimeout: [Function: clearTimeout],
  setInterval: [Function: setInterval],
  setTimeout: [Function: setTimeout] {
    [Symbol(nodejs.util.promisify.custom)]: [Getter]
  },
  queueMicrotask: [Function: queueMicrotask],
  performance: Performance {
    nodeTiming: PerformanceNodeTiming {
      name: 'node',
      entryType: 'node',
    },
    timeOrigin: 1668661015517.959
  },
  clearImmediate: [Function: clearImmediate],
  setImmediate: [Function: setImmediate] {
    [Symbol(nodejs.util.promisify.custom)]: [Getter]
  }
}
Object [console] {
  log: [Function: log],
  warn: [Function: warn],
  dir: [Function: dir],
  time: [Function: time],
  timeEnd: [Function: timeEnd],
  timeLog: [Function: timeLog],
  trace: [Function: trace],
  assert: [Function: assert],
  clear: [Function: clear],
  count: [Function: count],
  countReset: [Function: countReset],
  group: [Function: group],
  groupEnd: [Function: groupEnd],
  table: [Function: table],
  debug: [Function: debug],
  info: [Function: info],
  dirxml: [Function: dirxml],
  error: [Function: error],
  groupCollapsed: [Function: groupCollapsed],
  Console: [Function: Console],
  profile: [Function: profile],
  profileEnd: [Function: profileEnd],
  timeStamp: [Function: timeStamp],
  context: [Function: context]
}

 

콘솔 객체는

브라우저에서는 디버깅이 나옴

디버깅 콘솔에 접근 할 수 있는 친구, 브라우저마다 다르게 동작(미묘)

이 객체는 글로벌에 위치하고 있어서 어디서든 사용이 가능한 console.log

 

time, timeEnd 뒤의 값은 같아야함 ("시간")

time 에서 시작해서 timeEnd까지 초를 세는 것 

 

table 콘솔을 표 형태로 보여줌

 

dir 객체 구조 (단계)를 보여준다.

obj라는 객체 구조, { colors : true >  다른색으로 보여준다 / flase > 같은색 

depth : 1 ~ 2  > 1단계, 2단계(키와 값을 보여줌)  

console.log를 많이 쓰는 이유...

 


Timer 메소드

함수로 많이 이용한다.

 

setTimeout

밀리초 이후 실행될 작업(지연함수)

setInterval

시간마다 실행 할 함수를 정함(반복적으로 실행하도록 정의)

 

setTimeout

즉시 실행하는 함수

 

setImmediate

앞에서 실행해놓은 것을 실행전에 취소

 

clearImmediate

반복작업들을 취소해놓는 함수

 


문제! 03-timer.js 를 실행했을 때 console.log 에 어떤 순서로 나올지 예측하시오.

const func1 = setTimeout(function(){
    console.log( "1.5초 후 실행 ");
}, 1500);
const func2 = setInterval(() =>{
    console.log( "1초 마다 반복 ");
}, 1000);
const func3 = setTimeout(() => {
    console.log( "func3 실행 ");
}, 3000);

setTimeout(() => {
    clearTimeout(func3);
    clearInterval(func2);

}, 2500);

const fun4 = setImmediate(() => {
    console.log("fun4 즉시 실행");
});
const fun5 = setImmediate(() => {
    console.log("fun5 즉시 실행");
});
clearImmediate(fun5);

일단 코드를 한번 쭉 읽는데,

fun4는 즉시실행이라 바로 실행을 한다.

func2 1초마다 반복

func1 1.5초 후 실행

func2 1초마다 반복

func3 3초때 실행대기하다가 취소당해서 끝남.

func5는 즉시 실행 + 실행 취소 있기때문에 나오지 않는다.

 

정답


__filename

현재 파일 경로

 

 

 __dirname

현재 파일(디렉토리) 경로

 

 

process 객체

현재 실행 중인 노드 프로세스 정보가 담긴 객체

 

os모듈 - 운영체제

얘는 내장모듈이라 require로 불러와야 합니다.

 

path 모듈

폴더랑 파일의 경로나 파일명을 구분 지을 수 있다.

extname 확장자만 가져오기

parse 구분지어 가져올 수 있는 모든 것을 보여준다. (ex, 확장자, 루트경로 등등)

 


실습 내장 모듈 이용하기

os 모듈

path 모듈


url 모듈

인터넷 주소를 쉽게 조작하도록 도와주는 모듈

 

searchParams

WHATWG 방식에서? 뒤의 부분을 처리하도록 도움

 

 

 

url이 보여주는게 obj가 class 객체라는 것을 알려준다고 한다.

 


console.log(string); 해서 보면

밑의 터미널을 보면 URL { ~ }

PS C:\Users\SBAUser\Desktop\github\SeSAC_1YS_Web\html\node> node '.\2022_11_17_URL실습.js'
URL {
  href: 'https://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=0&ie=utf8&query=sesac',
  origin: 'https://search.naver.com',
  protocol: 'https:',
  username: '',
  password: '',
  host: 'search.naver.com',
  hostname: 'search.naver.com',
  port: '',
  pathname: '/search.naver',
  search: '?where=nexearch&sm=top_hty&fbm=0&ie=utf8&query=sesac',
  searchParams: URLSearchParams {
    'where' => 'nexearch',
    'sm' => 'top_hty',
    'fbm' => '0',
    'ie' => 'utf8',
    'query' => 'sesac' },
  hash: ''

search : '? ~ ', 가 우리가 필요하다.

 

const searchParmas = new url.URLSearchParams(string.search);

 


구조 분해 할당

구조 분해 할당 구문은 배열이나 객체의 속성을 해체하여

그 값을 개별 변수에 담을 수 있게 하는 JavaScript표현식입니다.

 

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

 

구조 분해 할당 - JavaScript | MDN

구조 분해 할당 구문은 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 JavaScript 표현식입니다.

developer.mozilla.org

 

 

배열 구조 분해

할당문의 좌변에서 사용하여, 원래 변수에서 어떤 값을 분해해 할당할지 정의

 

1.기본 변수 할당

let list = ['apple', 'banana']; 

를 구조 분해 하려면, 원래 변수 let list 에서  어떤 값을 분해 할당할지 정의 한다.

 

var [y, z] = list;

배열은 순서대로여서 y는 'apple'이다.

let list = ['apple', 'banana'];
var [y, z] = list;
console.log(y); // 'apple'
console.log(z); // 'banana'

2. 선언에서 분리한 할당

변수의 선언이 분리 되어도 구조 분해 통해 값을 할당 가능하다.

var a, b;

[a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2

3. 변수 값 교환하기

구조 분해 할당 없이, 두 값을 교환하려면! 임시 변수가 필요하다

 

대입 연산자로 생각해보면

a = b // b의 값을 a에 넣는다

console.log(a); // 3 ( b의 값 3)

var a = 1;
var b = 3;

[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1

 

 

값을 대체하도록 만드는 식도 가능하다

let list = ['apple', 'banana'];
[item1, item2] = list;
// let item1 = list[0];
// let item2 = list[1];
// let item3 = list[2];
//라고 쳐야 할 것을 저렇게 배열을 해체해서 각각의 개별 변수에 담는다.

// 2의 값이 없으면 피치로해라 (있으니까 바나나로 온다) 3은 존재하지 않아서 기본값인 오렌지가 들어온다
// 구조분해를 하면서 이값이 없을때 대체를 할 수 있다.
[item1, item2 ='peach', item3='orange'] = list;
console.log( item1 );
console.log( item2 );
console.log( item3 );

//[배열 구조 분해]
let x = 1;
let y = 3;

let temp = x;
x = y;
y = temp;

[y,x] = [x,y]
//x,y를 배열로 만들고 그것을 구조 분해 하고, 값을 바꿔준다.
//[1 , 3]
//[a, b] = [ 1, 3]  위를 구조 분해
//(배열은 순서대로 인덱스기 때문에!)

위의 것들도 다 대입연산자로 생각하면 된다.

[y, x] =  [x, y]

y의 값에 temp값을 넣겟다 > temp는 x값을 받는다 > x는 1이다.  // y = temp = x = 1

y의 자리에 x값을 넣자 > x 값은 1

x를 보아하니 y값을 받겟다 > y의 값은 3


 

객체 구조 분해

//객체 구조 분해
let obj = {
    a: 'one',
    b: 'two',
    e: '1',
    f: '2',   
};

// let a = obj.a;
//객체 구조분해는 이름으로(키값을) 찾습니다. = 순서가 상관없다 
//let { a, b } = obj;
// b : key1 은  b의 이름을 key1으로 바꿈
let { b : key1, a, c = 'three' } = obj;
console.log( a );
console.log( key1 );
console.log( c );
//one two three

console.log( key1 ); //two

key1 은 값을 대입받는다

 

전개 연산자  rest

나머지 얘들을 다 가져옴 (배열, 객체를 전개해서 가져옴)
가장 마지막에 들어가야한다, 추출이 되고 나머지들을 가져오기 때문에
... 변수명 쓰면 나머지 친구들이 온다

나머지 연산자 의미 : 남아있는 매개변수들을 한데 모아 배열에 넣어라

//객체 구조 분해
let obj = {
    a: 'one',
    b: 'two',
    e: '1',
    f: '2',   
};

// let a = obj.a;
//객체 구조분해는 이름으로(키값을) 찾습니다. = 순서가 상관없다 
//let { a, b } = obj;
let { b : key1, a, c = 'three' } = obj;
console.log( a );
console.log( key1 );
console.log( c );
//one two three

//전개연산자
// 나머지 얘들을 다 가져옴 (배열, 객체를 전개해서 가져옴)
// 가장 마지막에 들어가야한다, 추출이 되고 나머지들을 가져오기 때문에?
//... 변수명 쓰면 나머지 친구들이 온다
let { b, ...rest } = obj;
console.log(b);
console.log(rest);
//{ a: 'one', e: '1', f: '2' }

위에서 rest 는 추출되고 난 후의 나머지 얘들을 배열, 객체 등으로 전개해서 가져온다.

위에서 a, e, f는 사용되지 않아서 rest에 찍힘

 

예시1

중첩된 객체 및 배열의 구조 분해

var metadata = {
    title: "Scratchpad",
    translations: [
       {
        locale: "de",
        localization_tags: [ ],
        last_edit: "2014-04-14T08:43:37",
        url: "/de/docs/Tools/Scratchpad",
        title: "JavaScript-Umgebung"
       }
    ],
    url: "/en-US/docs/Tools/Scratchpad"
};

var { title: englishTitle, translations: [{ title: localeTitle }] } = metadata;

console.log(englishTitle); // "Scratchpad"
console.log(localeTitle);  // "JavaScript-Umgebung"

대입연산자로 생각해보자

console.log(englishTitle); // "Scratchpad"

englishTitle 값의 자리는

title: englishTitle  좌변에 위치>  우변의 title : '값' 을 받는 자리

> title: "Scratchpad"

 

console.log(localeTitle);  // "JavaScript-Umgebung"

localeTitle의 자리는

translations: [{ title: localeTitle }] 는 좌변 위치  =  우변의 translations 키 속에 title이란 목록키의 값을 받는 곳

> title: "JavaScript-Umgebung"

 

 

예시2 함수 매개변수로 전달된 객체에서 필드 해제하기

function userId({id}) {
  return id;
}

function whois({displayName: displayName, fullName: {firstName: name}}){
  console.log(displayName + " is " + name);
}

var user = {
  id: 42,
  displayName: "jdoe",
  fullName: {
      firstName: "John",
      lastName: "Doe"
  }
};

console.log("userId: " + userId(user)); // "userId: 42"
whois(user); // "jdoe is John"

 

class 는 객체를 만든다.

construtor는

  • 생성자 함수이며 객체를 생성하기 위해 사용되는 특수한 함수
  • 함수랑 다른 점 : 이름 첫 시작 대문자로!
  • 그리고 this. 로 접근해서 키 값을 할당 ( this.color = color; )
  • 객체를 생성하기 전에 실행되도록 초기화 하는 특별한 메서드
//car2파일
//class Car라는 객체
//constructor 생성자
class Car {
    constructor(color){
        this.color = color;
        this.isDoor = true;
    }
    move(){
        console.log('움직인다.');
    }
    stop(){
        console.log('멈춘다.');
    }
    returnColor(){
        return this.color;
    }
};
module.exports = { Car };
//car 객체를 감싸서 모듈로 내보냄

//car1파일
const {Car} = require('./2022_11_17_class_car2');
console.log(Car);

//constructor new 생성자
//constructor(color) 기본값이 컬러를 받고 있음
var car1 = new Car('red');
console.log( car1.returnColor() );
var car1 = new Car('blue');
console.log( car1.returnColor() );
var car1 = new Car('yellow');
console.log( car1.returnColor() );

 

 


콜벡 함수

callback : 함수가 끝난 뒤 실행되는 함수

비동기 함수에서 사용 된다.

함수 안에 파라미터로 함수를 넣어 받아서 사용한다

(셋타임아웃처럼!)

 

동기와 비동기의 특징

비동기는 동기처리가 다 끝나야 시작된다.

순차적으로 위에서 아래로 읽으면서

비동기 얘들을 다른 공간으로 분리시킨다.

비동기 얘들도 분리된 공간에서 동시에 실행이 되고, 그것들이 대기 공간으로 간다.

동기 얘들이 순차적으로 실행되고, 대기 공간에 있던 비동기 얘들이 실행 된다.

 

비동기로 순서가 맞지 않을때

동기로 만들어주기 위해 콜벡 함수를 사용한다

A라는 비동기 함수가

다른 공간으로 분리 되어 실행 될 때, 안의 B, C는 실행되지 않는다.

함수 속 함수 = 콜벡은

껍데기를 하나씩 벗기도록  순서를 강제하는 것과 같다.

A 벗기면, B 벗기고! 후에 C를 벗겨!

return의 기능

  • 함수 실행 종료
  • 주어진 값을 함수 호출지점으로 반환
  • 값을 명시하지 않으면, undefined를 반환

콜백 지옥 (callback Hell)

  • 비동기 프로그래밍 시 발생하는 문제
  • 함수의 매개변수로 넘겨지는 콜백 함수가 반복되어 코드의 들여쓰기가 너무 깊어지는 현상
  • 가독성 낮고 코드 수정 난이도가 높아진다.

넣고 넣고 넣어 버리면 끝이 없어진다.

 


추가실습. 콜백함수

[조건1]
  1. call 함수는 2초 후 실행
  2. back 함수는 1초 후 실행
  3. hell 함수는 0.5초 후 실행
하도록 setTimeout 이용하기[조건2] 실행결과를 아래 이미지처럼 나오게 하기
function call(name) {
    console.log("사용자는 " + name);
    return "call";
}
function back() {
    return "back";
}
function hell() {
    return "hell";
}

let a = call('kim');
console.log( "시작은 " + a);
let b = back();
console.log( "두번째는 " + b );
let c = hell();
console.log( "세번째는 " + c);

 

'SeSAC 풀스택 > Nodejs' 카테고리의 다른 글

2022-11-22 Express, ejs 수업  (0) 2022.11.23
2022_11_19_프로미스  (0) 2022.11.19
callback  (0) 2022.11.17
노드.js  (0) 2022.11.15
2022-11-12 서버  (0) 2022.11.12