1. import 정리
- 앞으로 import 할 일이 많아질텐데, server.js가 불필요하게 난잡해질 수 있음
- 그리고 이 것들이 server와는 상관이 없으므로 init.js라는 새로운 파일을 생성하고 모든걸 초기화
- 즉 init.js는 필요한 모든 것들을 import 시키는 역할
// init.js
import "./db";
import "./models/Video";
import app from "./server";
const PORT = 4000;
const handleListening = () =>
console.log(`✅ Server listening on port http://localhost:${PORT}`);
app.listen(PORT, handleListening);
// server.js
import express from "express";
import morgan from "morgan";
import globalRouter from "./routers/globalRouter";
import videoRouter from "./routers/videoRouter";
import userRouter from "./routers/userRouter";
const app = express();
const logger = morgan("dev");
app.set("view engine", "pug");
app.set("views", process.cwd() + "/src/views");
app.use(logger);
app.use(express.urlencoded({ extended: true }));
app.use("/", globalRouter);
app.use("/videos", videoRouter);
app.use("/users", userRouter);
export default app;
// package.json
"scripts": {
"dev": "nodemon --exec babel-node src/init.js"
},
- server.js의 역할은 express 된 것들과 server의 configuration에 관련된 코드만 처리
2. callback promise
- https://mongoosejs.com/docs/queries.html
- mongoose query를 사용하는 방법에는 callback function을 활용하거나, promiss를 활용하는 방법이 있음
- 이걸 이해하기 위해서는 javascript, callback, promiss의 작동방식을 이해해야 함
- callback은 무언가가 발생하고 난 다음 호출되는 function을 뜻함
- callback은 쉽게 생각하면 javascript에서 기다림을 표현하는 하나의 방법
- 가장 가까운 예로는 init.js에 있는 app.listen(PORTNUMBER, callback)을 찾을 수 있음
- 우린 데이터가 전송되는 것을 기다려야 하는데, 시간이 얼마나 걸릴지는 모르나 완전하게 전송될 때 까지 기다려야 함
- 하지만 그 도중에 에러가 발생할 수도 있는데, 우리가 받는 데이터는 javascript에 파일 속이 아닌 db 안에 있기 때문
- console.log는 javascript 내에서 처리되고 코드를 읽고 동시에 출력되고 바로 다음 작업으로 넘어가는 것과 대비됨
// videoController.js
export const home = (req, res) => {
// {}은 search terms이며, 비어있으면 모든 형식을 찾음
// callback은 err와 doc라는 signature를 가짐
// mongoose는 Video.find({}, 여기서 db를 불러오고
// db가 반응하면 mongoose는 (error, videos))를 실행
Video.find({}, (error, videos) => {
console.log("errors", error);
console.log("videos", videos);
});
console.log("hello");
res.render("home", { pageTitle: "Home", videos: [] });
};
// console
hello
GET / 304 109.610 ms - -
errors null
videos []
- home을 이렇게 수정하고 서버가 재가동되고나면 이상하게도 hello가 우선적으로 출력됨
- morgan을 사용하여 나오는 logger는 request가 완성되면 출력이 됨
- 서버와 연결이 되고, 그다음 hello가 출력되고, template을 render한 다음, error와 videos가 출력됨
- template을 render하는 과정을 거쳐야 logger가 발생XXXXXXXXX
- / page를 request 하고, hello를 출력한 뒤, render하는 과정을 거쳐야 logger가 발생
- 우리가 reponse를 요청해서 받은 다음, 다시 전송했다는 것
- callback 은 결국 마지막에 실행되게 한다는 걸 염두해야함
export const home = (req, res) => {
Video.find({}, (error, videos) => {
res.render("home", { pageTitle: "Home", videos: [] });
});
};
- home을 이렇게 수정하면 videos는 videos argument에서 오고, 브라우저는 해당 작업이 끝날때까지 기다림
- 즉, db에서의 검색이 끝나야 render가 시작된다는 것
- 이렇게 하는 이유는 db 검색이 안끝났을때 render 되는걸 방지하기 위함임
- 이전엔 API로 영화 데이터를 가져왔을때 서버가 실행된 직후 데이터가 나오지 않았고, 새로고침을 한번 하면 조회가 되었음
- callback의 장점은 error가 발생하면 Video.find({}, (error, videos)에서 바로 볼수 있음
- 추가적인 코드없이 error를 바로 볼수 있음
- 하지만 callback을 사용하는 방식은 function안에 function이 들어가고, 여간 번거로웠음
- 이걸 해결하기 위해 promis를 사용해볼거임
3. Promise
- promise는 callback의 최신 버전
export const home = async (req, res) => {
try {
const videos = await Video.find({});
return res.render("home", { pageTitle: "Home", videos });
} catch (error) {
return res.render("server-error");
}
};
- find앞에 await을 명시하면 find는 우리가 callback을 필요로 하지 않는다는걸 알게 되고 Video를 출력하게 됨
- await가 좋은 점은 db를 기다려줌
- javascript는 기다리는 기능이 없었고 코드를 위에서부터 순차적으로 읽었기 때문에 작업별로 꼬이는 경우가 발생했음
- 이런 문제를 해결하기 위해 callback을 사용했었지만 await의 등장한 이후 달라졌음
- await은 규칙상 function안에서만 사용가능하며, 해당 function이 asynchronous 일 때만 가능
- error를 출력하기 위해서는 try catch문을 사용함(java때 배웠던 그것)
4. Return Render
export const home = async (req, res) => {
Video.find({}, (error, videos) => {
return res.render("home", { pageTitle: "Home" }, videos);
});
};
export const watch = (req, res) => {
const { id } = req.params;
return res.render("watch", { pageTitle: `Watching: ${video.title}` });
};
- 기존의 return이 당장 작동하지 않는 이유는 function 안이기 때문
- function 안의 return은 그냥 function을 마무리할 뿐임
- 현재는 home에서 return되는 것은 아무것도 없음
- 하지만 watch function에서는 return 하고 있음
- 이 부분을 통해 express의 작동원리를 조금이나마 알 수 있으므로 중요함
- 사실 return 여부는 크게 중요하지 않으며 작동도 잘 되는데, 중요한 것은 우리가 어떤 function을 호출했는가임
- 현 상태에 home에 res.render를 한번 더 하면 안됨
- return이 없기 때문에 res.render가 두개 있어도 모두 실행은 되지만 오류가 발생함
- https://danielrepo.tistory.com/20(방장이 초기에 겪었던 그 문제)
'개발 > Node.js' 카테고리의 다른 글
More Schema, Router 수정 (0) | 2024.11.04 |
---|---|
실제 데이터를 입력해보기 (0) | 2024.11.04 |
CRUD (0) | 2024.11.01 |
Mongoose (0) | 2024.11.01 |
POST method (0) | 2024.10.31 |