예를 들어서 다음과 같은 코드를 쓰고 싶을 때가 있다.
router.get('/search', function(req, res){ var result = getSomethingFromDatabase(req.query.keyword); /* do something with result */ } function getSomethingFromDatabase(keyword){ var sql = 'SELECT * from TABLE' + 'WHERE column LIKE \'%' + keyword + '%\''; conn.query(sql, function (err, results) { return results; }); }
하지만 conn.query 가 호출되고 results 를 반환하기 전에 이미 search 메서드는 비어있는 변수 result 로 나머지 부분을 실행하게 되므로 원하는 결과는 나오지 않는다.
conn.query 메서드 안에 원하는 로직을 전부 넣으면 동작이 되지만,
웬지 그런방식으로 코드를 작성하고 싶지 않아서 열심히 구글링을 한 결과 async 나 promise 같은 것들이 있다는 걸 알게되었다.
그러면 둘의 차이는 무엇일까?
알아본 결과, Async 는 러닝 커브가 작으며 코드가 좀 더 깔끔해지는 장점이 있고, Promise 는 ECMA6 표준으로 채택되었다고 한다.
주목할 점은 Promise 를 사용해 작성한 코드가 동기 프로그래밍 방식과 상당히 닮아있다는 점인데, 이에 관해서는 내가 찾은 어느 블로그에 상세히 설명되어 있다.
결국 Promise 는 Async 에 비교하여 단순히 스타일이 다른 비동기 프로그래밍 방식이 아닌 동기 프로그래밍에 가깝게 작성하는 방법이고, 그 다음 구현체가 ES7의 async/await 라고 볼 수 있겠다.
나는 우선 둘 중에 표준인 Promise 로 구현해 보기로 했다.
ES6 를 사용중이라면 아무런 준비과정 없이 바로 Promise 를 사용할 수 있고
아니라면 npm 으로 설치해야 한다.
> npm install promise그리고 MDN의 promise 문서를 참고해서 기존의 코드를 수정했다.
router.get('/search', function (req, res) { /* create new promise object */ var promise = new Promise( function (resolve, reject) { var sql = 'SELECT * from TABLE' + 'WHERE column LIKE \'%' + keyword + '%\''; conn.query(sql, function (err, results) { if (err) { console.error(err); reject(err); } resolve(results); }); } ); /* do something with result */ promise.then(function (results) { res.render('view/result', result); }, function (err) { throw err; }); });
Promise 객체를 생성하면서 비동기 함수가 성공적으로 수행되었을 때(resolve), 또는 실패하였을 때(reject)의 경로를 정의해준다.
그리고 then( OnFullfilled, OnRejected )을 사용한 부분이 실제 비동기 함수를 호출하는 부분이다.
결론적으로 썩 내가 원하던 코드의 모습은 아니지만(데이터 불러오는 루틴을 밖으로 빼고 싶었음) 방식은 비슷하게 구현된 것 같다.
나중에 ES7 의 async/await 를 사용하면 코드가 훨씬 간결해질 듯 하다.
댓글 없음:
댓글 쓰기
댓글