nodejs Callback 지옥 벗어나기

NodeJs 2014. 7. 15. 00:28

제가 쓰는 mongodb-mongoose 는 모든 요청의 결과를 비동기로 처리하도록 되었지요.


이게 문제인게 간단한 회원가입에 대한 처리도 아래와 같은 로직을 흐르게 됩니다.



 

아마도 스프링과 같은 기본적으로 동기식이라면 저게 뭐가 어려워? 라고 하겠지만
NodeJS 는 대다수의 IO 동작이 Callback 에 의해서 동작한다
(이건 NodeJS 의 동작과 연관된 부분이다.)

그래서 실제 코드에서는 요청에 대한 처리 결과가 모드 비동기이기 때문에 전혀 다른 곳에 정의를 해야했고 대다수의 동작들이 완벽하게 시나리오에 의한 정의만으로 되어 있습니다.

이러한 문제 때문에 콜백을 처리할 수 있는 좀 더 코드가독성을 높일 방법을 찾을 수 밖에 없었습니다.

그러다가 알게된 Q 라는 라이브러리를 알게 되었습니다. 본디는 Promises 라는 개념이 있다는 것을 알게 되고 nodejs 모듈을 검색했더니  Q 가 제일 높은 점유율을 보여주고 있어서 선택했죠.

자 그럼 Q 라이브러리를 통해 개선된 코드를 보여드리겠습니다.

    userdao.findOne(email)
        .then(function(findObject) {
            console.log("Find : " + findObject);
            throw new Error("It has same email");
        }, function(err) {
            console.log("Error : " + err);
            if (!err) {
                return userdao.save(email, pwd, name);
            } else {
                throw err;
            }

        })
        .then(joinSuccess, joinFail);

Q 에 의해 정의된 로직을 구현하면 위와 같이 각 단계별 로직을 하나의 코드페이지에서 관리할 수 있게 됩니다.


userdao.findOne(email) 의 정의는 아래와 같습니다.

var deferred = Q.defer();

    UserModel.findOne({email: email}, function (err, findObject) {

        if (findObject) {
            deferred.resolve(findObject);
        } else {
            if (!err) {
                deferred.reject(new Error("No Item"));
            } else {
                deferred.reject(err);
            }
        }

    });

    return deferred.promise;

위에서 보듯이 Q.defer() 를 통해 로직은 Q 에 의해 관리되는 것이라 선언 후 promise 객체를 반환하여 다음 처리를 예약할 수 있도록 하였습니다.
코드 내의 콜백은 defer.reject() 또는 defer.resolve() 를 통해서 Success, Fail 를 실행하도록 되어 있습니다.

이러한 라이브러리를 소개하는 가장 큰 이유는 모바일 어플리케이션을 개발하는 과정에서 정말 많이 고민했던 부분입니다.

특정 앱에서는 시나리오 단계가 10단계 가까이 가는 경우가 있었는데 이런 경우 각 단계별 성공 실패를 정의하다보면 A 클래스, B 클래스등을 날아다녀야 하는 경우가 많았습니다.

이러한 해결책을 Nodejs 에서 만나게 될 줄은 몰랐네요.

Callback 지옥에서 벗어나는 큰 도움이 된 라이브러리였습니다 :)

'NodeJs' 카테고리의 다른 글

nodejs Callback 지옥 벗어나기  (0) 2014.07.15
NodeJS 의존성 라이브러리 관리  (0) 2014.03.16
NodeJS 와의 첫 만남  (0) 2014.03.16

설정

트랙백

댓글