elice/WIL

[week_06] asyncHandler, Pagination, PM2 Process Manager

1. asyncHandler

  • request handler를 async function으로 작성하면서 try ~ catch, next를 자동으로 할 수 있도록 구성한 아이디어
  • requestHandler를 매개변수로 갖는 함수형 미들웨어
  • 전달된 requestHandler는 try ~ catch로 감싸져 asyncHandler 내에서 실행
  • throw되는 에러는 자동으로 오류처리 미들웨어로 전달되도록 구성됨
const asyncHandler = (requestHandler) => {
	return async(req, res, next) => {
    	try {
        	await requestHandler(req, res);
        } catch(err) {
        	next(err);
        }
    }
}


// ---------------------------------------


router.get('/', asyncHandler(async (req, res) => {
	const posts = await Posts.find({});
    if(posts.length < 1) {
    	throw new Error('Not Found');
    }
    res.render('posts/list', {posts});
});

 

2. Pagination

  • 데이터를 균일한 수로 나누어 페이지를 분리하는 것
rouger.get(... => {
	// 현재 페이지
	const page = Number(req.query.page || 1)
    // 페이지 당 게시글 수
    const perPage = Number(req.query.perPage || 10)
})
  • 일반적으로 url query를 사용해 전달 👉 /posts?page=1&perPage=10
  • MongoDB의 limitskip을 사용하여 pagination 구현 가능
router.get(... => {
	...
    const total = await Post.countDocument({});
    const posts = await Post.find({})
    	.sort({createdAt: -1})
        .skip(perPage * (page -1))
        .limit(perPage);
    const totalPage = Math.ceil(total / perPage);
    ...
})
  • limit = 검색 수 제한 (perPage)
  • skip = 검색 시 포함하지 않을 데이터 수
  • pagination 시에는 데이터의 순서가 유지될 수 있도록 sort를 사용
  • 게시글 수 / 페이지 당 게시글 수 = 총 페이지 수
mixin pagination(path)
  p
    - for (let i = 1; i <= totalPage; i++)
    a(href=`${path}?page=${i}&perPage=${perPage}`)
      if i == page
        b= i
      else
        = i
      = " "
      
      
 // --------
 include pagination
 tr
   td
     +pagination("/posts")
  • pagination을 mixin으로 선언
  • pagination이 필요한 페이지에서 해당 템플릿을 include한 후, +pagination으로 mixin을 사용함
  • 현재 페이지는 b태그로 굵게 표시

 

3. PM2 Process Manager

  • Node.js의 작업을 관리해주는 Process Manager
  • 작업 관리를 위한 다양하고 유용한 기능 제공
  • 안정적인 프로세스 실행, 빠른 개발환경, 배포 시 편리한 관리 등의 장점
module.exports = {
	apps : [{
    	name: 'simple-board', // 실행되는 프로세스 이름 설정
        script: './bin/www', // 실행되는 스크립트, =npm start
        watch: '.', // 현재 디렉터리를 전부 바라보겠다
        ignore_watch: 'views', // views 디렉터리 안의 부분들은 변경 되어도 프로젝트 재실행 x
    }],
};
$ pm2 start
  • $ pm2 init simple 혹은 pm2 init 명령어를 이용하여 pm2 설정파일 예제를 만들 수 있다.
  • 예제를 수정하여 설정파일 생성후 pm2 start 명령어를 실행하면 어플리케이션을 pm2 데몬으로 실행
  • 개발 시 watch 옵션 사용하여 파일 변경 시 서버 자동 재실행 구성