2014-01-22 3 views
3

저는 Node에 비교적 익숙하지만 이전에 PHP로 수행되었던 RESTful API를 통해 이식하는 것이 성공적이었습니다. 꽤 많은 데이터베이스 상호 작용이 있습니다. 결과적으로 나는 노드의 비동기 성질로 인해 많은 사람들이 "운명의 피라미드"라고 부르는 것을 알게되었습니다.Q를 Node-Mysql과 함께 사용하기

결과적으로 Q 라이브러리를 사용하여 약속을 구현하는 데 찌그러 뜨 렸습니다. 그러나 아직 많은 성공을 거두지 못했으며 데이터를 가져와야한다고 생각할 때 null 결과 집합을 다시 얻습니다. 다음은 Q를 추가하기 전에 현재의 구조입니다. 누군가가 Q를 올바르게 구현하는 방법에 대해 조언 할 수 있다면 그 예제로 실행하고 나머지 모델/memcached 호출을 해당 모델로 변환 할 수 있습니다. 무엇을 달성 할 싶습니다

// helper function to get a company row 
getRow = function(lookUp, callback) { 
    var query = db.query('SELECT * FROM table WHERE lookUp = ?', lookUp, function(err, result) { 
     var count = Object.keys(result).length; 

     if(count == 0) { 
      return; 
     } else { 
      callback(null, result); 
     } 
    }); 
} 

// function that uses the above helper method 
insertItem = function(request, response) { 
    var data = JSON.parse(request.body.data); 
    var message = data.message; 
    var lookUp = data.lookUp; 

    security.verifyToken(lookUp, function (lookUpError) { 
     if (lookUpError) { 
      var errorResult = { "response": "error", "msg": lookUpError }; 
      response.json(errorResult); 
      response.end(); 
     } else { 
      getRow(lookUp, function (companyError, row) { 
       var companyId = row[0].id; 

       var res = helper.insertFeedItem(companyId, message, function (insertError, insertResult) { 
        var result = (feedError) ? { "response": "error", "msg": insertError} : insertResult; 
        response.json(result); 
        response.end(); 
       }); 
      }); 
     } 
    }); 
} 

같은 것을 할 수있는 것입니다 : 다시 최선의 Q를 구현하는 방법에 어떤 통찰력을

var result = getCompanyRow(lookUp); 
companyId = result.company_id; 

을 (또는 일반적으로 약속)이 경우는 것을 위해 매우 감사드립니다.

* 편집 :

여기

내가 지금까지 Q를 구현하는 시도 것입니다,하지만 내가 말한대로 내가 다시 아무것도 받고 없습니다입니다.

function getRow(id) { 
    var dfd = Q.defer(); 
    var query = db.query('SELECT * FROM table WHERE lookUp = ?', id, function(err, result) { 
    if(err) { dfd.reject(err); } 
    else { dfd.resolve(result); } 
    }); 
    return dfd.promise; 
} 

result = getRow (id)로 호출하면 위의 기능이 작동하지 않습니다. 나는 Q.all을 사용하고 그 함수에 바인딩을 시도했지만 그 접근법을 시도 할 때 나는 아무것도 얻지 못했다. 나는 .then()에 대한 나의 부름에 무엇을 포함시킬 지 확신하지 못했지만 여러 가지를 시도했지만 아무도 성공하지 못했습니다. 그것은 더 node adapter methods from Q를 사용하여 간단하게 할 수 :-)

+0

'callback '을 결코 호출하지 않는 getRow는 약속이 없더라도 나쁜 생각입니다. 적어도'콜백 (nothingFoundError) '을 수행하십시오. – Bergi

+0

약속을 사용하는 방법을 보여 주시겠습니까? – Bergi

+0

@Bergi가 추가되었습니다. 내가 알고있는 것은 매우 미숙한데, 몇 번의 시행 착오 끝에 내가 남긴 것은 전부다. –

답변

4

귀하의 getRow 약속 기능 유망 같습니다

function getRow(id) { 
    return Q.nfcall(db.query, 'SELECT * FROM table WHERE lookUp = ?', id); 
    //  ^^^^^^^^^^^^^^^^^^^^ 
    // or .ninvoke(db, "query", … if it must be called as a method 
} 
// or even just 
var getRow = Q.nbind(db.query, db, 'SELECT * FROM table WHERE lookUp = ?'); 

내가 (기능을 그 때는 사용에 대한 혜택을 볼 수 없습니다 .. .) 콜백처럼 중첩이 필요하기 때문에.

(떨어져 쉽게 오류 처리에서) 장점은 여러 개의 작업을 체인에서 오는, 즉 또한 security.verifyTokenhelper.insertFeedItem 방법은 약속을 반환 할 때. 그렇지 않은 경우 (그리고 수정할 수없는 경우) 위 예제와 같이 Q.nfcall을 계속 사용할 수 있습니다. 가정하면 코드는 다음과 같이 단순화 될 수 있습니다

function insertItem(request, response) { 
    var data = JSON.parse(request.body.data); 

    security.verifyToken(data.lookUp).then(function(/* no lookupError */) { 
     return getRow(data.lookUp); // potentially catch SQL errors here 
    }).then(function(row) { 
     return helper.insertFeedItem(row[0].id, data.message); 
     // What was the `res` it had returned before? 
    }).catch(function(someError) { // lookUpError, companyError, insertError 
     return { "response": "error", "msg": someError }; 
    }).done(function(result) { 
     response.json(result); 
     response.end(); 
    }); 
}