callback
의 장점은 에러들을 바로 볼수 있다는거다.
추가적인 코드 없이 에러들을 바로 불러 올수 있다. 바로 이렇게 해볼 수 있다.
export const home = (req, res) => {
console.log("Start");
Video.find({}, (error, videos) => {
if (error) {
return res.render("server-error");
}
return res.render("home", { pageTitle: "Home", videos: [] });
});
console.log("I finish first");
};
if (error){
return res.render("server-error");
}
이렇게 해줄수가 있다. 하지만 callback
을 좋아하지 않는 이유는
function
안에 function
을 작성하는 걸 싫어 하기 때문이다.
뭔가 세련된 코드 처럼 안 느껴진다. (필자는 아직 왜 그런지 이유는 잘 모르겠다.)
그래서 promise
를 사용할 거다. promise
는 callback
의 최신 버전이라고 생각하면 된다.
promise
를 사용하면 장황한 코드를 쓸 필요가 없다.
import Video from "../models/Video";
Video.find({}, (error, videos) => {});
export const home = (req, res) => {
return res.render("home", { pageTitle: "Home", videos: [] });
};
Video.find({}, (error, videos) => {});
callback
과 비교 할수 있도록 이 코드는 남겨둘거다. 저 부분이 callback
의 코드이다.
그리고 promise
는 이렇게 생겼다.
import Video from "../models/Video";
// Video.find({}, (error, videos) => {});
export const home = async (req, res) => {
console.log("I Start");
const videos = await Video.find({});
console.log("I finish");
console.log(videos);
return res.render("home", { pageTitle: "Home", videos: [] });
};
결과를 확인하기 위해 console.log()
을 중간 중간에 넣어 주었다. 어떤 차이가 있는지 보여줘야 해서
// Video.find({}, (error, videos) => {});
주석 처리 하였다.
현재는 awit
와 async
에 대해 몰라도 상관없다. callback
과의 차이를 이해하는 것이 중요하다.
서버를 재시작하고 새로고침을 하고 터미널을 확인해 보면
I Start
I finish
[]
GET / 304 184.973 ms - -
보다시피 모든 코드가 순서대로 실행되고 있다.
I Start
가 출력되고, 비디오를 찾고, I Finish
그리고 array
를 출력한다.
저 과정이 끝나면 render
가 실행된다.
callback
과의 차이점은 await
를 find
앞에 적으면 find
는 callback
을 필요로 하지 않는다는걸 안다.
그렇기에 find
는 찾아낸 비디오를 바로 출력해 주는거다. find operation
의 결과 값으로 말이다.
callback
과 느낌이 조금 다르다.
에러를 출력하기 위해서는 try catch
문을 사용해야 한다.
export const home = async (req, res) => {
try{
console.log("Start");
const videos = await Video.find({});
console.log("finish");
console.log(videos);
return res.render("home", { pageTitle: "Home", videos: [] });
} catch{
return res.reder("server-error")
}
};
말 그대로 무엇인가를 try
하고 에러가 있다면 그 에러들을 catch
하게 해준다.
그 다음 res.render
를 통해 오류들을 출력 해준다.
단순한 예시이다.
만약 이걸 javascript
방식으로 사용한다면 이렇게 적어야 한다.
Video.find({}, (error, videos) => {
if(error){
return res.reder("server-error")
}
return res.render("home", { pageTitle: "Home", videos: [] });
});
이렇게 적는 건 코드를 비교하기 위함이다. 만약 callback
방식으로 하게 되면 이렇게 해야 한다.
export const home = async (req, res) => {
try {
const videos = await Video.find({});
return res.render("home", { pageTitle: "Home", videos: [] });
} catch {
return res.reder("server-error");
}
};
이건 promise
방식이다. promise
가 try
와 catch
를 사용한다는 건 알겠는데
await
는 왜 사용 할까? await
는 database
를 기다려 준다.
이전 파트에서 이런 코드를 본적이 있을 것이다.
console.log("Start")
Video.find({}, (error, videos) => {
if(error){
return res.reder("server-error")
}
return res.render("home", { pageTitle: "Home", videos: [] });
});
console.log("Finished")
여기서 Start
, finished
그 다음에 videos
를 출력했다.
왜냐하면 javascript
는 기다리는 기능이 원래 없었다.
그저 위에서 아래로 순서대로 코드를 읽어냈었다.
하지만 작업별로 실행되는 시간이 달라 순서가 다르게 나왔고 그래서 callback
이란 해결책을 썼다.
callback
어떤 동작이 끝나면 특정 function
을 부르도록 만들어졌다.
왜냐하면 javascript
는 기다리는 기능이 없기 때문이다.
그저 위에서 아래로 순서대로 코드를 읽는다.
하지만 이 모든건
await
가 쓰이면서 달라졌다.
await
만 있다면 javascript
는 계속 기다려준다. database
에게 결과값을 받을 때까지이다.
그리고 async
와 await
는 callback
보다 최신 기술이다.
async
와 await
의 최대 장점은 직관적이라는 거다.
왜냐하면 javascript
가 어디서 어떻게 기다리는지 바로 알 수 있기 때문이다.
callback
에서는Start
,Finished
다음에videos
를 출력해준다.
하지만 promise
의 경우에는 순서대로 위에서 아래로 코드가 실행 된다.
이 작은 차이가 엄청 큰거다. 왜냐하면 이렇게 하면 코드를 읽을때 정말 이해하기가 편하다.
코드를 읽다가 awit
를 보면 바로 이 생각을 하면 된다.
javascript
가 무엇인가를 기다리고 있다.
코딩 규칙상
await
는function
안에서만 사용이 가능하다.
해당 function
이 asynchronous(비동기)
일 때만 가능하다.
그렇기에 async
를 적어주는 거다. 규칙이다.
오류들을 다뤄 보도록 하자
callback
의 경우 어디 무엇이 오는지 모든 건 명확한데 promise
는 아직 명확하지 않다.
두가지 옵션이 있다. 첫번째는 try
를 사용하는 것인데 이 방법은 res.render
를 실행하다
const videos = await Video.find({});
return res.render("home", { pageTitle: "Home", videos: [] });
에러 발생 시, 이 코드로 넘어가서 실행시키는 거다.
return res.reder("server-error");
에러를 인식하는 것이 catch
의 기능이다.
다시 한번 짚고 넘어 가자면 예를 들어 database
가 꺼졌거나, 연결이 끊겼거나, 사람이 포화 상태거나,
어떤 에러가 발생하든 javascript
는 await
내 출력 값을 출력 안 하고 아래 에러 출력 코드를 실행 시키는 거다.
이것이 가능 한 것도 await
가 있기 때문이다.
계속 말하지만 이 operation
의 await
가 있는 코드에 오류가 있다면
await
가 있는 코드는 출력 되지 않는다. 바로 에러 출력 코드가 발생 할 거다.
참고로 에러 메세지는 이 코드를 통해 받을 수 있다.
export const home = async (req, res) => {
try {
const videos = await Video.find({});
return res.render("home", { pageTitle: "Home", videos: [] });
} catch (error) {
return res.reder("server-error", { error });
}
};
그리고 필요하다면 오류 메세지를 추가 해줄수도 있다.
하지만 지금은 그렇게 하지 않을 거다. 일단 에러에 대해서는 여기까지만 다루도록 한다.
export const home = async (req, res) => {
const videos = await Video.find({});
return res.render("home", { pageTitle: "Home", videos: [] });
};
이렇게 만 작성을 해준다. promise
가 확실히 callback
보다 훨씬 보기에도 더 좋다.