전 단계에서 하던 걸 이어서 해보도록 하겠다.
Video.find({}, (error, videos) => {
});
mongoose
는 Video.find({}
이 부분을 database
에서 불러 올거다.
그리고 database
가 반응하면 mongoose
는 이 function
(error,videos)
을 실행 시킬거다.
그 다음 mongoose
는 err
와 video
의 값을 불러 올거다.
작성한 코드는 같은 거다.
videoController.js
에서
const handleSerch = (error, videos) => {
console.log("errors", error);
console.log("videos", videos);
}
export const home = (req, res) => {
Video.find({}, (handleSearch);
return res.render("home", { pageTitle: "Home" });
export const home = (req, res) => {
Video.find({}, (error, videos) => {
console.log("errors", error);
console.log("videos", videos);
});
return res.render("home", { pageTitle: "Home" });
};
이제 에러가 하나 뜬텐데 왜냐하면 render home
은 videos array
가 필요 하기 때문이다.
일단 임시적으로 쓸 빈 videos array
를 추가해 주도록 한다.
return res.render("home", { pageTitle: "Home", videos: [] });
};
이렇게 하면 callback
에게만 집중하게 된다.
(현재 서버를 재시작을 할 경우 세이브만 해서는 재시작이 안된다. npm run dev를 새로 해줘야 한다.
아직까진 왜 이런지 이유를 알수가 없다.)
home
페이지로 돌아가서 실행하면 nothing was found.
상태이다.
이건 빈 array
를 보내서 생긴거니까 상관없다.
Video.find({}, (error, videos) => {
console.log("errors", error);
console.log("videos", videos);
});
관심 가져야 할 것은 바로 이 코드이다.
✅ Server listening on port http://localhost:4000 🚀
✅Connected to DB
GET / 200 190.043 ms - 592
errors null
videos []
터미널을 확인해 보면 이렇게 나온다. 에러도 없고 비디오는 빈 array
이지만
이거는 javascript
코드로 database
와 아무런 에러 없이 통신을 했다는 얘기이다.
callback
을 사용하면 아무것도 return
되지 않아야 한다.
예시로 한번 직접 작동 시켜 본다.
export const home = (req, res) => {
Video.find({}, (error, videos) => {
console.log("errors", error);
console.log("videos", videos);
});
console.log("hello");
return res.render("home", { pageTitle: "Home", videos: [] });
};
console
에 hello
를 넣어준 다음 코드를 재실행 해보면 어떻게 되는 건지 알수 있다.
hello
GET / 304 154.623 ms - -
errors null
videos []
실행 결과를 보면 원래 생각 했던 대로 작동을 하지 않는다.
보다시피 hello
가 먼저 출력되고 errors
와videos
가 출력된다.
출력되는 순서가 중요하다. hello
가 먼저 나오고, errors
그 다음 videos
왜냐하면 코드상 에서는 errors
와 videos
가 더 윗줄에 있기에 순서는
error,
video,
hello
순서로 나와야 하는데 그렇지가 않다.
이렇게 된 과정을 하나씩 보도록 하자.
logger
는 request
가 완성되면 출력이 되야 한다.
연결이 되고 그 다음 hello
가 출력되고 template
을 render
한 다음 errors
와 vidoes
가 출력된다.
이 과정은 오래 걸리지는 않지만 약간의 시간이 걸린다. 별거 아닌듯 보이지만 정말 엄청난 발견이다.
그러니깐 꼭 기억해야 한다. 이 page
를 request
하고 console.log("hello")
를 출력한 다음
render
과정을 거쳐야 logger
를 얻게 되는 거다.
요청해서 받은 response
를 보면 이말은 response
를 요청해서 받은 다음 다시 전송했다는 말이다.
그리고 render
와 responde
과정 이후에 console.log
값들을 출력 할수 있다는 것이다.
이건 해당 operation
을 rendering
전에 했어도 저 순서를 따라야한다.
export const home = (req, res) => {
Video.find({}, (error, videos) => {
console.log("errors", error);
console.log("videos", videos);
});
console.log("hello");
return res.render("home", { pageTitle: "Home", videos: [] });
};
이런식으로 프로세스를 짰지만 hello
가 출력되고 render
그리고 logger
가 더 빨리 완료 되었다.
그 이후에 먼저 작성한 코드도 실행되었다.
좀 더 좋은 예를 들자면
export const home = (req, res) => {
console.log("Starting Search");
Video.find({}, (error, videos) => {
console.log("Finished Search");
});
console.log("I should be the last one");
return res.render("home", { pageTitle: "Home", videos: [] });
};
이렇게 코드를 변경을 해본 다음 페이지를 새로 고침해서 돌아와서 터미널을 보면
Starting Search
I should be the last one
GET / 304 176.936 ms - -
Finished Search
database
검색이 먼저 이뤄졌고 마지막에 있는 코드 가 실행되었고
그 다음 finished Search
가 출력 되었다. 이게 바로 callback
의 힘이다.
특정 코드를 마지막에 실행되게 하는 거다.
이제 이걸 응용하기 위해서 코드를 옮겨 준다.
export const home = (req, res) => {
console.log("Start");
Video.find({}, (error, videos) => {
console.log("Finished");
return res.render("home", { pageTitle: "Home", videos: [] });
});
};
이 코드로 인해 videos
는 위 videos argument
에서 올거다.
browser
는 해당 작업이 끝날때 까지 기다려 줄거다.
코드를 새로고침 했을때 바뀐 부분 없이 잘 실행 되지만 이제는 database
검색이 끝나야 rendering
이 시작된다.
이제 database
검색 시작과 종료가 이루어지면 render
가 시작된다.
지금까지 callback
의 위대함을 알아보는 시간이었다. 코드에 따라 실행되는 시간이 다를수가 있다.
export const home = (req, res) => {
console.log("Start");
Video.find({}, (error, videos) => {
console.log("Finished");
return res.render("home", { pageTitle: "Home", videos: [] });
});
console.log("I finish first");
};
여기에 console.log()
를 추가해 줘서 확인해 본다.
Start
I finish first
Finished
GET / 304 285.739 ms - -
확인해 보면 srart
가 제일 먼저 실행되고 그 다음 I finish first
가 호출되고 finished
가 출력되었다.
실행 속도의 차이가 이제 보인다. 물론 지금의 경우는 render
를 기다리고 있다.
이건 database
검색이 안 끝났을 때 render
되는 걸 방지 하기 위함이다.
이 방식이 두 방법중에 하나이고 그렇게 나쁘지는 않다.
하지만 function
안에 function
을 넣어야 하는 것이 번거롭다.
그래서 이 문제를 해결할 두번째 방법은 다음 파트에서 해보도록 한다.