2014-01-22 84 views
3

我對Node相對來說比較新,但是在通過先前在PHP中完成的RESTful API移植方面取得了很好的成功。有很多數據庫交互,因此我發現自己陷入了我認爲由於Node的異步性質,許多人稱之爲厄運的金字塔。在Node-Mysql中使用Q

因此,我嘗試使用Q庫實現承諾,但是我還沒有獲得太多成功,並且當我相信我應該獲取數據時,仍然收到空結果集。下面是我添加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(); 
       }); 
      }); 
     } 
    }); 
} 

我想什麼做到的是能夠做這樣的事情:

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

同樣,任何洞察到如何最好地實現Q(或只是一般的承諾),這種情況下會非常感謝。

*編輯:

這是我迄今對執行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()的電話中包含什麼,但我嘗試了很多事情,但都沒有成功。

+0

即使沒有承諾,一個'getRow'可能永遠不會調用它的'callback'是一個壞主意。至少做一個'回調(nothingFoundError)' – Bergi

+0

你能否也請告訴我們你使用承諾的方法? – Bergi

+0

@Bergi已添加。我知道的非常粗糙,但這是我經過幾輪試驗和錯誤後所剩下的一切。 –

回答

4

getRow承諾的功能看起來很有希望:-)它可以通過使用node adapter methods from Q進一步簡化:

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.verifyToken方法helper.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(); 
    }); 
}