2014-09-09 16 views
10

Tôi tạo nhiều truy vấn mongoDB trong vòng lặp. và muốn gửi tất cả các kết quả dưới dạng một mảng dữ liệu. Nhưng khi tôi đơn giản sử dụng trả về để gửi dữ liệu, nó đơn giản trả về không xác định và không đợi kết quả của tất cả các yêu cầu DB. Tôi cũng đã cố gắng sử dụng q.moulde nhưng cùng một vấn đề.Sự cố trong dữ liệu trả về được truy xuất từ ​​các truy vấn DB được gọi trong vòng lặp

Code:

var getPrayerInCat = function(data){ 
    var result ; 
    var finalData = []; 
    if(data.length >0){ 
      data.forEach(function(data2){ 
       var id= data2.id; 
       Prayer.find({prayerCat:id},function(err,prayer){ 
        var deferred = Q.defer() 
        if (err) { // ... 
         console.log('An error has occurred'); 
         // res.send(err); 
         result= finalData = err 
        } else { 
         if(!prayer){ 
          // console.log(data2.id+'--0'); 
          data2.prayersCount = 0; 
          result = deferred.resolve(finalData.push(data2)) 
         } else { 
          // console.log(data2.id+'--'+prayer.length); 
          data2.prayersCount = prayer.length; 
          // console.log(prayer) 
          result = deferred.resolve(finalData.push(data2)) 
         } // else for data forward 
        } 
        deferred.promise; 
       }) 
       // deferred.resolve(finalData); 

      }) 
      /*if(finalData.length > 0) { return finalData;}*/ 
     } 
} 

FinalData được trả về xác định.

+0

'q.moulde' là gì? – Bergi

+0

lời hứa của nó. Tôi có thể loại bỏ nó, tôi đã cố gắng để giải quyết các prob vì vậy tôi đã cố gắng điều này –

+0

chức năng của bạn 'getPrayerInCat()' không trả lại bất cứ điều gì hoặc trả lại bất cứ điều gì để gọi lại. Ngoài ra, sẽ hữu ích nếu bạn xóa các nhận xét khỏi mã của mình và cập nhật bài đăng của mình để bao gồm những gì đầu ra ngoại trừ của bạn. Và bạn nên trả lại 'deferred.promise; ', thay vì chỉ hiển thị nó? –

Trả lời

14

Hãy bắt đầu với các nguyên tắc chung cho việc sử dụng những lời hứa:

Mỗi chức năng mà một cái gì đó không đồng bộ phải trả lại một lời hứa

Những chức năng này trong trường hợp của bạn? Đó là getPrayerInCat, gọi lại số forEachPrayer.find.

Hm, Prayer.find không trả lại lời hứa và đó là chức năng thư viện để chúng tôi không thể sửa đổi. Quy tắc 2 đến chơi:

Create an immediate wrapper cho mỗi chức năng đó không

Trong trường hợp của chúng tôi đó là dễ dàng với Q's node-interfacing helpers:

var find = Q.nbind(Prayer.find, Prayer); 

Bây giờ chúng tôi đã chỉ hứa hẹn xung quanh, và không cần bất kỳ sự trì hoãn nào. quy tắc thứ ba đi vào chơi:

Tất cả mọi thứ mà làm điều gì đó với một kết quả async đi vào một callback .then

... và trả về kết quả. Địa ngục, kết quả đó thậm chí có thể là một lời hứa nếu "cái gì đó" là không đồng bộ! Với điều này, chúng tôi có thể viết chức năng gọi lại hoàn chỉnh:

function getPrayerCount(data2) { 
    var id = data2.id; 
    return find({prayerCat:id}) 
// ^^^^^^ Rule 1 
    .then(function(prayer) { 
// ^^^^^ Rule 3 
     if (!prayer) 
      data2.prayersCount = 0; 
     else 
      data2.prayersCount = prayer.length; 
     return data2; 
//  ^^^^^^ Rule 3b 
    }); 
} 

Bây giờ, chúng tôi có điều gì đó phức tạp hơn một chút: vòng lặp. Liên tục gọi getPrayerCount() sẽ nhận được nhiều lời hứa, có nhiệm vụ không đồng bộ chạy song song và giải quyết theo thứ tự không xác định. Chúng tôi muốn chờ tất cả chúng - tức là nhận được lời hứa giải quyết mọi kết quả khi mỗi tác vụ đã kết thúc.

Đối với các nhiệm vụ phức tạp như vậy, không nên cố gắng để đưa ra giải pháp của riêng bạn:

Kiểm tra API của thư viện của bạn

Và đó chúng tôi tìm Q.all, mà thực hiện chính xác điều này.Viết getPrayerInCat là một làn gió bây giờ:

function getPrayerInCat(data) { 
    var promises = data.map(getPrayerCount); // don't use forEach, we get something back 
    return Q.all(promises); 
// ^^^^^^ Rule 1 
} 

Nếu chúng ta cần phải làm bất cứ điều gì với mảng Q.all quyết tâm, chỉ cần áp dụng Rule 3.

+0

Tôi đã sử dụng mã của bạn nhưng cùng một vấn đề nó trở lại hình thức tìm và donot chờ đợi để resukt từ db. Vì vậy, kết quả cuối cùng là không xác định. –

+0

getPrayerCat (''). Sau đó (function (data) { getPrayerInCat (dữ liệu) }). Sau đó (function (data2) { console.log (data2) }) var getPrayerInCat = function (data) { kết quả var; var finalData = []; nếu (data.length> 0) { var promise = data.map (getPrayerCount); trả về Q.all (hứa hẹn); } } –

+0

hàm getPrayerCount (dữ liệu 2) { var id = data2.id; trở find ({prayerCat: id}) .Sau đó (function (cầu nguyện) {! if (cầu nguyện) data2.prayersCount = 0; khác data2.prayersCount = prayer.length; trở data2; }) ; } –

Các vấn đề liên quan