2012-06-30 44 views
0

我有一些JavaScript函數,通過網絡執行異步請求,並通過回調「返回」數據。下面是這是什麼樣子,當我使用它的一個例子:擺脫嵌套所需的JavaScript回調

RemoteQuery(server,query,function(ret) { 
    // do something with ret 
}) 

的問題是,如果我有幾個疑問連續變得相當嵌套和困難的代碼來管理。由於我依賴於範圍變量,因此我無法將這些函數中的每一個都分解爲單獨的頂級函數。這裏是一個玩具例子:

RemoteQuery(server,query1,function(ret) { 
     var x = ret[5] 
     RemoteQuery(server,query2,function(ret) { 
      var y = ret[3] 
      if (x + y > 10) { 
       RemoteQuery(server,query2,function(ret) { 
        // do more stuff 
       }) 
      }  
     }) 
}) 

顯然,如果我有超過2次或3的查詢它開始變得醜陋,我可能有很多比這更!

理想情況下,我想在沒有嵌套的情況下表示上述內容,例如

ret = RemoteQuery(server,query1) 
var x = ret[5] 
ret = RemoteQuery(server,query2) 
var y = ret[3] 
if (x + y > 10) { 
    ret =RemoteQuery(server,query2) 
    // do more stuff 
} 

但我想到的是唯一可能的工作將是解析JavaScript中,承認其有回調函數,它們在正確的形式,和eval重新寫,但這似乎非常複雜,並會使調試非常困難。

有沒有更好的機制來做到這一點?

+0

數組函數怎麼樣? –

+0

jQuery有這種可以幫助你的「延遲」技術,但我不知道你是否可以使用它。 – MaxArt

回答

1

'正確'的方法是爲它們編寫函數聲明並避免依賴範圍變量(因此將它們傳遞給每個函數)。喜歡的東西:

var myFunc1 = function(x, ret1) { 
    RemoteQuery(server, query, function(ret2) { 
    var y = ret[3]; 
    myFunc2(x, y, ret2); 
    }); 
}; 

var myFunc2 = function(x, y, ret) { /* do more stuff */ }; 

RemoteQuery(server, query, function(ret1) { 
    var x = ret[5]; 
    myFunc1(x, ret1); 
}); 

既然你已經異步調用這些RemoteQuery(IES),有沒有辦法真正做到你在你的問題提出解決方案。使用Deferred對象可能會訣竅,但我認爲你仍然需要重構你的函數(因爲你的目標是避免嵌套)。

+0

對於將來參考這個的人,當我學習NodeJS時,我選擇了這個模型,因爲這是大多數演示/示例應用程序的構建方式(節點通常需要大量的嵌套)。 –

0

如果你願意使用框架JQuery以及Dojo(我確信其他人也有它!)包含一個延期的對象,這將是一個不錯的選擇。

0

鏈式函數的數組如何?

function R1 (server, query, callback) 
{ 
    RemoteQuery(server, query, function(ret) { 
     // process ret 
     if (x + y > 10) 
      callback(); 
    } 
} 

function R2 (server, query, callback) 
{  
    RemoteQuery(server, query, function(ret) { 
     // process ret 
     callback(); 
    } 
} 

function R3 (server, query, callback) 
{ 
    RemoteQuery(server, query, function(ret) { 
     // process ret 
     callback(); 
    } 
} 

var functions = [R1, R2, R3] 

function callAll(a, server, query) 
{ 
    var callNext = function(callback, i) 
    { 
     if (i < a.length) 
      a[i](server, query, function() { callback(callback, i + 1); }); 
    } 
    callNext(callNext, 0); 
} 

callAll(functions, 'server', 'query'); 
+0

這樣你不需要所有的jquerys和dojos等;] –