2014-02-13 66 views
7

我正在做一種使用藍鳥庫的QA(問題/答案)應用程序。所以這裏是場景:如何打破諾言中的循環?

  1. 用戶用一些問題(如5個問題)的答案填寫表格。
  2. 一個問題,有超過1個可能的答案:使用node.bcrypt
  3. 當通過回答循環,如果用戶回答場比賽,就沒有必要繼續檢查「問題有很多答案」數據庫
  4. 答案被加密(bcrypt)這個問題的答案。

所以這是一個常見的問題來解決做同步的事情,但我有點失去做與承諾異步。

這裏是什麼,我不知道如何進行樣本:

.then(function(answers) { 
    var compare = Promise.promisify(bcrypt.compare); 
    // foreach answer, I need to check like this 
    // compare(answer.password, user.password).then(function(match){ 
    //  if (match) break; <-- something like this 
    // }) 
    }) 
+0

您可能需要循環之前分別得到加密的答案,並在回調中開始循環,只是做基本檢查'(如果哈希==密碼)break;' – tymeJV

+0

@tymeJV我想我不能這樣做,因爲當我用bcrypt對密碼進行哈希處理時,會從數據庫以前生成的值生成一個不同的值...這就是之所以我需要bcrypt比較功能...也許我錯了... – rizidoro

+0

不要讓我的bcrypt回購在我面前,但這聽起來是正確的 - 回調地獄:\ - 這篇文章可能會有所幫助:http: //stackoverflow.com/questions/13214862/async-functions-inside-foreach-loops-with-js – tymeJV

回答

3

假設你要撥打的compare小號順序,這將做到這一點:

.then(function(answers) { 
    var compare = Promise.promisify(bcrypt.compare), 
     i = 0; 
    return Q(false).then(function checkNext(res) { 
     return res || 
       i<answers.length && compare(answers[i++].password, user.password) 
            .then(checkNext); 
    }); 
}) 

它將「遞歸「步驟通過answers數組,停止第一個true結果。要返回正確答案(而不是僅僅true爲「發現」)或null(如果沒有找到),如@ Noseratio的代碼,你可以使用

var i = 0, answer; 
    return Q(false).then(function checkNext(res) { 
     return res ? answer : (i<answers.length || null) && compare((answer = answers[i++]).password, user.password).then(checkNext); 
    }); 

或更好的更詳細的

function next(i) { 
    if (i < answers.length) 
     return compare(answers[i].password, user.password).then(function(res) { 
      return res ? answers[i] : next(i+1); 
     }); 
    else 
     return null; 
} 
return next(0); 
1

的以下解決方案(未測試)實現一個狀態機以模擬foreach循環。比賽已經發現,當result承諾解決,或當沒有更多的答案進行比較:

.then(function(answers) { 
    var result = new Promise(); 
    var i = 0; 
    function nextStep() { 
     if (i >= answer.length) 
     result.resolve(null); 
     else { 
     var answer = answers[i]; 
     if (compare(answer.password, user.password).then(function(match) { 
      if (match) 
      result.resolve(answer); 
      else { 
      i++; 
      nextStep(); // do the next step 
      } 
     }) 
     } 
    } 
    process.nextTick(nextStep); // do the first step asynchronously  
    return result; // return the result as a promise 
    });