2014-06-11 2 views
0

필자는 쿼리를 해당 함수의 이름을 가진 함수에 넣음으로써 '기능화'하고 싶습니다.Node.js 및 Node-Postgres : 모델에 쿼리 넣기

req, res 함수 (내 컨트롤러)에 모든 것을 넣는 것을 피하고 대신 정렬의 '모델'즉, 가져오고 쿼리를 실행하는 데 사용되는 다른 JavaScript 파일에 넣고 컨트롤러 대신 결과를 반환하십시오. 내가 쿼리에있어 동안, 나는 기본적으로 리디렉션하고있는 페이지를 렌더링,

exports.userAccount = function(req, res, next) { 
    var queryText = "\ 
     SELECT *\ 
     FROM users\ 
     WHERE id = $1\ 
     "; 

    var queryValues = [168]; 

    pg.connect(secrets.DATABASE_URL, function(err, client, done) { 

     client.query(queryText, queryValues, function(err, result) { 

     res.render('pathToSome/page', { 
       queryResult: result.rows 
      }); 
     }); 
    }); 
} 

여기

UserController.js :

내가 쿼리에 대해 다음 설정을 가지고 있다고 가정 데이터. 그건 잘 작동합니다. 하지만 그 모든 것을 pg.connect 코드와 client.query 코드로 가져 와서 별도의 파일로 옮겨서 모델로 가져 오려고합니다. 나는 다음과 같이 왔어요 :

UserModel.js

exports.findUser = function(id) { 

    // The user to be returned from the query 
    // Local scope to 'findUser' function? 
    var user = {}; 

    var queryText = "\ 
     SELECT *\ 
     FROM users\ 
     WHERE id = $1\ 
     "; 

    var queryValues = [id]; 

    pg.connect(secrets.DATABASE_URL, function(err, client, done) { 

     client.query(queryText, queryValues, function(err, result) { 

     // There is only ever 1 row returned, so get the first one in the array 
     // Apparently this is local scope to 'client.query'? 
     // I want this to overwrite the user variable declared at the top of the function 
     user = result.rows; 

     // Console output correct; I have my one user 
     console.log("User data: " + JSON.stringify(user)); 
     }); 
    }); 

    // I expect this to be correct. User is empty, because it was not really 
    // assigned in the user = result.rows call above. 
    console.log("User outside of 'pg.connect': " + JSON.stringify(user)); 

    // I would like to return the user here, but it's empty! 
    return user; 
}; 

나는 그래서 내 모델 함수를 호출하고 있습니다 :

var user = UserModel.findUser(req.user.id); 

쿼리는이에 완벽하게 정상적으로 실행 패션 - user 객체가 올바르게 할당되지 않았다는 것을 제외하고는 (범위 인 문제라고 가정하고 있습니다.) 알아낼 수 없습니다.

목표는 컨트롤러에서 함수를 호출하여 모델에서 쿼리를 실행하고 컨트롤러에 결과를 반환하도록하는 것입니다.

나는 여기서 뻔뻔스러워 보이는 것을 놓치고 있습니까?

답변

2

pgconnect은 비동기 호출입니다. 다음 라인으로 진행하기 전에 데이터베이스에서 데이터가 반환되기를 기다리는 대신 Postgres가 응답하기 전에 나머지 프로그램을 진행합니다. 따라서 위 코드에서 findUser은 아직 채워지지 않은 변수를 반환합니다.

제대로 작동하게하려면 findUser 함수에 콜백을 추가해야합니다. (나는 이전의 편집 잘못 말했 : pg.connect의 done 매개 변수는 연결 풀에 다시 연결을 해제하기 위해서라고합니다.) 최종 결과는 다음과 같이 보일 것이다 :

exports.findUser = function(id, callback) { 
    var user = {}; 
    var queryText = "SELECT FROM users WHERE id = $1"; 
    var queryValues = [id]; 
    pg.connect(secrets.DATABASE_URL, function(err, client, done) { 
     client.query(queryText, queryValues, function(err, result) { 
      user = result.rows; 
      done(); // Releases the connection back to the connection pool 
      callback(err, user); 
     }); 
    }); 
    return user; 
}; 

그리고 당신을 '사용 D,이 좋아하지 :

var user = myModule.findUser(id); 

을하지만이 같은 :

myModule.findUser(id, function(err, user){ 
    // do something with the user. 
}); 

수행하는 여러 단계가있는 경우, 이전 ASY에서 데이터에 대한 그들 각각의 의존 nchronous 호출을 사용하면 혼동을 일으킬 수있는 Inception 스타일의 중첩 콜백이 발생합니다. 이러한 코드를보다 쉽게 ​​읽을 수 있도록 도와주는 비동기 라이브러리가 여러 개 있지만 가장 널리 사용되는 모듈은 npm의 async 모듈입니다.

+0

답변 해 주셔서 감사합니다. - '완료'통화를 잊어 버렸습니다. 그러나,'pg.connect' 함수 나는 여전히 빈'user' 객체를 얻고 있습니다. 나는 올바른 방법이'pg.connect' /'client.query'의 결과를 얻는 것일 지 모르겠다. 하나는'done (results)'이 그것을 할 것이라고 생각 하겠지만, 보고있어. –

+0

findUser는 비동기 메서드를 포함하고 있기 때문에 비동기로 만들어 버리기 때문에이를 사용하여'var user = findUser (id)'와 같은 변수에 할당 할 수 없습니다. 콜백도 필요합니다. 내 대답을 편집 할게. – autodidact

+0

Brilliant! 비동기 작업 개념을 이해하지 못했을 것 같습니다. 나는이 프로젝트에서'async' 모듈을 사용하려고 생각하고 있었지만, 충분할 필요는 없다. 나는 또한'node-postgres' 위키 (문서)에서 비동기에 관해 아무것도 보지 못했고, 그래서 어디서부터 시작해야할지 몰랐습니다. 당신의 도움을 주셔서 감사합니다! –

관련 문제