2014-02-26 34 views
1

我是js的新手。 我使用express作爲節點js,並使用mongoose作爲mongo orm。javascript express js通過異步調用

function direct_tags_search_in_db(tags){ 
    var final_results = []; 
    for (var i=0; i<tags.length; ++i) { 
     var tag = tags[i]; 
     Question.find({tags: tag}).exec(function(err, questions) { 
      final_results.push(questions); 
      if (i == tags.length -1){ 
       return final_results; 
      } 
     }); 
    } 
}; 

由於find的異步性,我得到空結果。但我不知道這是最好的方法。

給予一點幫助,謝謝。

+0

你沒有異步思考。每個find()。exec'調用都是異步執行的,並且回調函數以任意順序(將來的任意時間)調用。您需要將回調傳遞給您的整體功能或開始使用承諾。 – squid314

回答

1

您經常會發現接受函數作爲參數的方法(如Question.find().exec)是異步的。執行網絡請求或文件系統操作的方法尤其常見。這些通常被稱爲回調。既然如此,如果您希望完成異步任務時發生某些情況,則還需要實現回調。

此外,您可能會對tag的引用以可能不期望的方式進行更改。有許多解決方案,這裏是一個簡單的解決方案。

function direct_tags_search_in_db(tags, callback){ 
    var final_results = []; 
    // Array.forEach is able to retain the appropriate `tag` reference 
    tags.forEach(function(tag){ 
     Question.find({tags: tag}).exec(function(err, questions) { 
      // We should be making sure to handle errors 
      if (err) { 
       // Return errors to the requester 
       callback(err); 
      } else { 
       final_results.push(questions); 
       if (i == tags.length -1){ 
       // All done, return the results 
       callback(null, final_results); 
       } 
      } 
     }); 
    }); 
}; 

你會發現,當我們實現我們自己的回調,我們遵循相同的通用模式的回調Question.find().exec(function(err, result){}); - 第一個參數一個潛在的錯誤,第二個參數的結果。這就是爲什麼當我們返回的結果,我們提供null作爲第一個參數調用這個函數的callback(null, final_results);

簡單的例子:

direct_tags_search_in_db([1, 2, 3], function(err, results){ 
    if (err) { 
    console.error('Error!'); 
    console.error(err); 
    } else { 
    console.log('Final results'); 
    console.log(results); 
    } 
}); 

解決各種異步目標,另一種選擇是async模塊,承諾,或除此以外。