2017-04-10 146 views
0

在我的應用程序,即時通訊使用貓鼬與藍鳥這樣的:在數據庫如何通過貓鼬找回文檔?

var mongoose = require('mongoose'); 
mongoose.Promise = require('bluebird'); 

在同一文件中,林持有其搜索「約會」的功能-documents。該函數的返回值應該是發現文檔的結果數組,而不是承諾,查詢或其他內容。

但不幸的是,它看起來像程序會跳回到調用函數,然後諾言將實現。那我該如何處理呢?

這是我在當前狀態下功能:

get_intersecting_appointment: function(appointment) { 

     var appointmentQuery = AppointmentModel.find({ 
      $and: [{ 
        begin: { 
         $lte: appointment.begin 
        } 
       }, 
       { 
        end: { 
         $gte: appointment.end 
        } 
       } 
      ] 
     }); 

     return appointmentQuery.then(function(appointments) { 
      debug("Found appointments:"); 
      debug(appointments); 

      if (appointments) { 
       return appointments; 
      } else { 
       return []; 
      } 

     }); 


    }, 

提示:調用函數內debug("Found appointments:")之前打印的「下一個調試輸出」;從上面。比方說,調用函數如下:

appointment_is_available: function(appointment) { 

     var appointments = dbcon.get_intersecting_appointment(appointment); 
     //... 
} 

回答

0

Node.js自然可以使用回調來解決這種類型的問題

使用callback

按照您的代碼,我試圖添加回調

get_intersecting_appointment: function(appointment,callback) { 

    var appointmentQuery = AppointmentModel.find({ 
     $and: [{ 
      begin: { 
       $lte: appointment.begin 
      } 
     }, { 
      end: { 
       $gte: appointment.end 
      } 
     }] 
    }); 

    return appointmentQuery.then(function(appointments) { 
     debug("Found appointments:"); 
     debug(appointments); 

     if (appointments) { 
      callback(null,appointments); 
     } else { 
      callback(null,[]); 
     } 

    }); 

}, 

//添加回調函數調用時它

appointment_is_available: function(appointment) { 

     var appointments = dbcon.get_intersecting_appointment(appointment,function(err,result){ 
      if(!err){ 
       consoole.log(result) 
      } 
     }); 
     //... 
} 

更新

您還可以使用Promiseasync module

+0

那麼即使這會正常工作,我寧願去異步代碼,因爲調用函數將被另一個函數被調用,我只是想避免建傳遞迴調的長鏈函數。另外,我必須在'appointment_is_available'函數內使用結果,因爲我只想從中返回一個布爾值。如果我只得到一個回調,該函數將在回調被調用之前返回,所以同樣的問題在這裏(沒有辦法等待像「than」或什麼的IMHO回調)。 –

+0

那麼,你可以使用'Promise'或[異步模塊](https://github.com/caolan/async) – abdulbarik

+0

是的,這就是起源問題:我上面的例子使用承諾與then方法,但它贏得了'在返回到調用函數之前等待then(...)的結果,這不是我期望的行爲。那麼我怎麼能在這裏等待履行諾言呢? –

0
var appointmentQuery = AppointmentModel.find({ 
      $and: [{ 
        begin: { 
         $lte: appointment.begin 
        } 
       }, 
       { 
        end: { 
         $gte: appointment.end 
        } 
       } 
      ] 
     }); 

具有以下

var appointmentQuery = AppointmentModel.find({ 
      $and: [{ 
        begin: { 
         $lte: appointment.begin 
        } 
       }, 
       { 
        end: { 
         $gte: appointment.end 
        } 
       } 
      ] 
     }).exec(); 

注意 -它使用一個很好的做法代替上面的代碼.exec()之後,每一個貓鼬操作使用承諾。因爲.exec()返回未決承諾。

現在來到您使用此功能的地方就像var appointments = dbcon.get_intersecting_appointment(appointment);。看到這裏dbcon.get_intersecting_appointment(appointment)這將返回一個承諾,您將分配給一個變量,它是異步的,因此在完成之前下一行將被執行。還有一件事從.then()返回的價值只能在另一個鏈接.then內訪問。您不能簡單地將從.then()返回的值分配給全局變量。您必須鏈接另一個then才能使用該值。您在致電dbcon.get_intersecting_appointment(appointment)時需要稍作修改。你需要做的是像這樣

dbcon.get_intersecting_appointment(appointment).then(function(res){ 
    //res is either empty array or the result array 
    //rest of your code here 

}) 
+0

我也試過這種方法,但它會導致像我的問題中的版本一樣的行爲。這很奇怪,因爲exec()返回的確實是一個承諾,但'return appointmentQuery.then(...)'行仍然不會等待'then'的結果並立即跳回。 :( –

+0

請看看我的更新答案。@MarcM – nurulnabi