즐코

require와 exports / JS 동작원리 / 콜백함수 본문

NodeJS

require와 exports / JS 동작원리 / 콜백함수

YJLEE_KR 2022. 1. 28. 15:37

1/ require 와 module.export

2/ 자바스크립트 동작 원리

3/ 콜백함수

 

1/ require 와 module.export

 

require은 Node.js의 모듈이고, require 문법은 표준 문법은 아니다.

표준에 없는데 왜 node.js는 이게 필요할까?

 

#1. require 왜 쓰는거지?

 

node.js에선 내가 실행할 파일만 해석해준다.

서로 다른 js 파일들이 같은 폴더 상에 존재해도 서로간의 데이터, 코드를 쉐어할수가 없다.

 

node.js에서는 어떻게 다른 코드들과 연결시켜줄까? 이 때 쓰는게 require다. 

반복되는 데이터, 기능별 코드를 묶어놓은 모듈을 다른 파일로 공유가 되게끔 도와준다.

 

그래서, express 라는 웹서버를 구축해주는 코드를 묶어논 패키지를 가져올 때 썼던 게 require('express') 였다. 

 

그렇게 파일/모듈/라이브러리를 가져오는 데 쓰는 구문엔 import 또는 require가 있다.

 

import - react에서 쓴다고 하니 생략하고 현재 배우고 있는 node.js의 require 부터 배운다..

 

 

#2. 사용방법

 

 받는 애는 require / 주는 애는 module.export 또는 exports

 

기존 browser에선 html 파일에다가 <script src="끌고오고싶은파일경로 및 파일명"></script> 를 치면 연결됨

하지만, node.js에선 데이터를 제공해주는 파일 상에도 코드를 쳐줘야 코드 공유가 가능하다.

 

간단한 예를 들자면, mainServer.js 가 메인파일 / datalist.js는 데이터를 모아둔 파일이라고 치자

 

1- 데이터를 받는 파일 : require('가져올 파일경로,파일명') 입력

 

let obj_datalist = require('./datalist.js')

 

 

2- 데이터를 제공해주는 파일 :  module.export = 보내고자하는 객체명 입력

module.exports는 객체 형태만 보낼 수 있다

 

let obj = {
    user:[
        {
            name:'ingoo'
        },
        {
            name:"ingoo2"
        },
    ]
}

module.exports = obj
메인 파일에서 console.log(obj_datalist) 출력해보면?
데이터 제공해주는 파일의 데이터를 가져왔다!

 

 

좀 더 자세히 뜯어보자면,, 

 

browser의 내장 객체에 window가 있듯이

node.js의 내장 객체에도 global, module이 있다.

 

console.log(module)해보면 아래와 같은 객체가 나오는데, 그 안에 export라는 객체가 있다.

즉, require는 exports의 속성값을 가져오는 거다. 

 

 

module 객체 안의 빈 exports 객체에 객체를 직접 할당하거나 함수를 추가하는 것도 가능하다.

 

 

 

# module.export 랑 exports는 뭐가 다른거지?

 

module.exports => 하나의 객체를 보낼 때, module.exports 자체에 객체를 할당한다. 
exports => 다수의 객체를 각각 보낼 때, exports의 속성으로 할당한다. 

 

#1. module.export 예시

module.export = 보낼 객체명 

 

console.log(module.exports) 해보면

 

#2. exports 예시

exports.담아줄 key값= value값

 

console.log(exports) 출력해보면,

 

코드 받은 파일 쪽 출력값


2/ 자바스크립트 동작 원리

 

JS == single threaded language

자바스크립트 엔진
- 한 개의 콜스택과 한 개의 메모리를 가지고 있다. 한번에 한가지 기능밖에 못함
- non-blocking code / 멈추지 않는다.

 

 

이럴 경우 중간에 시간이 오래 걸리는 작업이 있을 경우 그 뒤의 작업을 수행하지 못하므로 효율적이지 않다.

좀 더 효율적으로 작동하기 위해 자바스크립트엔진 이외의 백그라운드(웹API)테스크큐, 이벤트루프가 존재한다. 

 

 


3/ 콜백함수 

 

자바스크립트 이벤트리스너 배울 때 만났던 콜백함수 

https://yjleekr.tistory.com/26?category=1249724 

 

자바스크립트는 따지고 보면 코드가 총 2군데에서 처리되는데, 콜스택과 백그라운드(web API) 라고 한다.

 

콜스택이 아닌 백그라운드에 들어간 코드를 원하는 시점, 순서에 실행시키고 싶을 때 callback함수를 동원한다.

 

 

# 콜백함수 연습 - 자동차경주를 해보자

 

#1. SetTimeout에 넣은 두번째 인자인 시간을 직접 정하지 않고 랜덤하게 출발/도착할 수 있게끔 만들어보자.  

 

랜덤함수!  - Math.random()

Math.random() // 랜덤하게 1이하의 소수가 찍히는 함수
Math.random()*10 // 자릿수를 올려주려고
ParseInt(Math.random()*10) // 정수로 만들어주려고
(ParseInt(Math.random()*10))+1 // 1~10 범위로 만들어주려고
((ParseInt(Math.random()*10))+1)*1000 // SetTimeout에 넣기 좋게 1000단위로
let time = () => (ParseInt(Math.random()*10)+1)*1000 // 함수화 시켜주기

 

let time = (ParseInt(Math.random()*10)+1)*1000 // 변수로 지정할 경우 한번밖에 못사용함 (같은 숫자 나옴)

let time = () => (ParseInt(Math.random()*10)+1)*1000 // 함수화 시켜주는 게 랜덤으로 쓰기에 알맞음

 

 

 

#2. 소나타 출발,도착하면 제네시스 출발,도착하면 아반떼 출발,도착하는 순서로 만들기

    인자값으로 콜백함수 넣어주기! 

 

const 아반떼 = cb => { 
    setTimeout(()=>{
        console.log('아반떼 end')
        cb()
    },
    time())
    console.log('아반떼 go')
}

const 소나타 = cb => {
    setTimeout(()=>{
        console.log('소나타 end')
        cb()
    },
    time())
    console.log('소나타 go')
}

const 제네시스 = cb => {
    setTimeout(()=>{
        console.log('제네시스 end')
        cb()
    },
    time())
    console.log('제네시스 go')
}

 

console.log('경기시작~')
아반떼(()=>{
    소나타(()=>{
        제네시스(()=>{
            console.log('경기종료~')
        })
    })
})​

 


결과물


결과물은 어쨌든 나왔지만, 여기서 함수가 더 많아지면 함수 호출할때 더 지저분해질 예정ㅠ

 

 

그렇다면, 다음 문제.. 

 

시작은 동시에 (아반떼/소나타/제네시스) 이렇게 하고 도착은 랜덤으로 먼저 끝나는 경우에 먼저 출력되게끔

 

let timer = () => (parseInt(Math.random()*10)+1)*1000

    function 아반떼1(){
        console.log('아반떼 출발',)
        setTimeout(() =>{
            console.log('아반떼 도착')
        },timer())
    }
    
    function 소나타1(){
        console.log('소나타 출발')
        setTimeout(()=>{
            console.log('소나타 도착')
        },timer())
    }
    
    function 제네1(){
        console.log('제네시스 출발')
        setTimeout(()=>{
            console.log('제네시스 도착')
        },timer())
    }

	function 경기종료(){
        setTimeout(()=>{
            console.log('경기끝')
        },10000)
    }

아반떼1()
소나타1()
제네1()
경기종료()

 

랜덤하게 도착하는 결과는 나왔지만, 
경기종료는 억지로 10000s로 맞췄는데,,  이렇게 하면 안될듯 ㅋ 

 

콜백함수는 만드는 시점엔 그나마 괜찮은데 호출할 때 지저분해진다. 콜백지옥

이 콜백지옥을 벗어나게 도와주는 게 promise / async, await 라는데.. 아직 이해가 잘 안간다.

이건 다음 포스팅에서 정리해야지

Comments