2013-06-25 38 views
0

我有兩個使用Node.js/node-postgres lib/PostgreDB實現RESTful服務的問題,都是由於JS的異步性質。查詢具有自變量和同步查詢的回調

A)我需要傳遞一個額外的參數給回調client.query(查詢,回調)呼叫

我查詢的回調中,並通過最近取出的行從一個數組去一個數據庫,並希望推出後續查詢爲他們每個人:

var query = client.query('SELECT * FROM event', queryAllEventsHandler); 
function queryAllEventsHandler(err, result){   
    allEvents = result.rows; 

    /* allEvents is an JSON array with the following format 
    [ {"id_event":1, "name":"name of the event"}, 
     {"id_event":1, "name":"name of the event"} 
    ] 
    */ 

for(var i = 0; i<allEvents.length; i++){ 
    client.query('SELECT * FROM days where id_event = $1',[allEvents[i].id_event], function(err, result){ 
       //I want to have a reference to variable i 
    } 
} 

在上面的例子中,我想要做的事,如:

client.query('SELECT * FROM days where id_event = $1',[allEvents[i].id_event], function(AN_EXTRA_ARG, err, result) 

其中AN_EXTRA_ARG是一個額外的參數或回調函數中的閉包...我如何實現這一點?我是否應該使用i創建關閉並將其作爲回調的參數傳遞?怎麼樣 ? :|

B)「同步」查詢

我需要推出各種查詢,並從所有這些創建自定義JSON。由於每個查詢和它的回調都是異步的(等待沒有人),我正在尋找一種「馴服」它的方法,除此之外,我首先找到了一個解決方案,但似乎有點「糟糕/糟糕「: 保持查詢計數真的是要走的路@jslatts建議在Synchronous database queries with Node.js

希望我

回答

0

A)我個人很喜歡lodash(或者,如果你喜歡下劃線)partial()這一點。它接受一個函數和多個參數,並返回一個函數,其中提供的參數已應用,其餘參數仍然打開。這很像currying的功能概念。

B)對於組合多個異步結果,我強烈建議async。這個語法稍微習慣一些,但是這樣做很容易。快速樣品:

async.parallel([ 
    one: function(callback){ 
     db.fetch(options, callback); 
    }, 
    two: function(callback){ 
     db.fetch(options, callback); 
    } 
], 
function(err, results){ 
    // this callback will get called when either parallel call gives an error 
    // or when both have called the callback 
    if (err) { 
     // handle error 
     return; 
    } 

    // get the results from results.one and results.two 
}); 

==加在編輯==

其實lodash還提供了一個更好的(恕我直言)雖然稍貴(因爲函數調用)爲您的問題的解決方案):

_(allEvents).each(function(event, index, array) { 
    client.query('SELECT * FROM days where id_event = $1',[event.id_event], function(err, result) { 
     // Just use 'index' here, which doesn't change during the each 
    } 
}); 
+0

感謝您的提示......部分給了我一個想法,使用bind()...謝謝....將肯定看看異步...我不想數數電話:) – luigi7up

1

關於問題A,您可以創建一個函數來處理您的兩個查詢,並僅在執行最後一個查詢時返回並將兩個結果都返回給回調。

for(var i = 0; i<allEvents.length; i++){ 
    query(client, allEvents[i], function(result1, result2) { 
    //do something 
    }); 
} 

function query(client, event, callback) { 
    client.query('SELECT * FROM days where id_event = $1',[event.id_event], function(err1, result1){ 
     client.query('SELECT * FROM days where id_event = $1',[event.id_event], function(err2, result2){ 
      callback(result1, result2); 
     }); 
    }); 
} 
1

我不喜歡回答我的問題,但這可能是有人感興趣的....關於我的問題的一部分。您可以在您的功能中爲指定一個自定義對象

正如你所知道的關鍵詞對應窗口(頂部)對象時函數內部(除非它是一個方法的功能)。使用綁定功能,您可以將其引用更改爲您自己的對象...

所以我所做的就是,我創建了一個名爲功能queryCallback

function queryCallback(err, result){ 
     //this == Window (default)    
} 

改變了匿名回調函數來命名一個queryCallback

client.query('SELECT * ... where id_event = $1',[allEvents[i].id_event], queryCallback.bind({"position":i}, err, result)); 

現在,請注意queryCallback .bind({「position」:i},err,result));

什麼綁定(my_custom_this,[其他參數])確實是其結合自定義對象(在我的情況下{「位置」:ⅰ})到在其上結合被調用的函數的內部。 ..

現在我們有這樣的場景:

function queryCallback(err, result){ 
      //this == {"position":i} 
} 

綁定解釋說:http://fitzgeraldnick.com/weblog/26/

+0

我想這將在這個特定的情況下工作。但是如果你想訪問原始範圍呢?你通常會使用'\ .bind(this)',但你已經使用過。我想你可以'綁定({position:i,context:this})',但它不會變得更漂亮。 – mtsr

0

對於B),您的選擇包括異步或通過一個Promise庫(如Q,when.js,Bluebird等...)