2010-09-22 86 views
1

我正在編寫一些JavaScript/jQuery代碼,它要求我向各種API發出大量請求。我多次遇到這個問題,這只是一個實例的基本例子。使用回調函數和異步請求時避免重複

該代碼向服務器發出異步請求,然後如果不符合返回數據的條件,代碼將發出另一個請求。第二個請求有一個回調,其中包含許多與其父代相同的邏輯。我知道我通過在每個回調中調用returnFunction來避免重複,但是有沒有辦法完全避免這種情況?

var container = []; 

$.getJSON("http://www.url.com/api/?callback=?", 
{ data: "mydata" }, 
function(data) { 
    if(!data.length) { 
     // No results 
    } else { 

     // Put the results into an array 
     $(data).each(function(k, v){ 
      container.push(v.some_data); 
     }); 

     // If the query did not return enough results 
     if(data.length < limit) { 
      var number_missing = limit - data.length; 

      // Get some more results and append to the array 
      myFunctionToGetSomethingElse(number_missing, function(response){ 

       // Add these results to the array 
       $(response).each(function(k, v){ 
        container.push(v.some_data); 
       }); 

       // Do something with this data 
       returnFunction(response); 
      }); 

     } else { 
      // Do something with the result 
      returnFunction(data); 
     } 
    } 
}); 

你會如何建議我避免重複回調中的代碼?這是唯一可行的方法嗎?

回答

1

有一個圖書館提供「分層的JavaScript」。奇怪的是,它將異步調用包裝爲一個順序範例。回到原點:)

看看oni labs

+0

接受你的答案的詳細信息。雖然tomg的回答非常有幫助!看起來像一個非常酷的工具。 – betamax 2010-09-23 08:38:14

0

我沒有你的問題的答案 - 如何消除重複 - 但一種方法,使這個更清潔一點是將它與早期回報平平。

$.getJSON("http://www.url.com/api/?callback=?", 
{ data: "mydata" }, 
function(data) { 
    if (!data.length) { 
     // No results 
     return; 
    } // no "else" needed, because we left the function 

    // Put the results into an array 
    $(data).each(function(k, v){ 
     container.push(v.some_data); 
    }); 

    // if the query DID return enough results, return them and exit 
    if (data.length >= limit { 
     // Do something with the result 
     returnFunction(data); 
     return; 
    } // again, no "else" needed; we don't need to deeply nest the code 

    // The query did not return enough results 
    var number_missing = limit - data.length; 

    // Get some more results and append to the array 
    myFunctionToGetSomethingElse(number_missing, function(response){ 

     // Add these results to the array 
     $(response).each(function(k, v){ 
      container.push(v.some_data); 
     }); 

     // Do something with this data 
     returnFunction(response); 
     }); 
    } 
}); 

我想你可以將數組加載循環包裝到它自己的函數中;我不明白爲什麼這會是一個問題,但我不完全瞭解JavaScript,絕對有信心這麼說。

2
// <script src="http://code.onilabs.com/0.9.1/oni-apollo.js"></script> 
// <script type="text/sjs"> 

// install stratified versions of jquery functions; see below 
require('jquery-binding').install(); 

// Note the extra '$' in $getJSON. This is the 'stratified' version of 
// getJSON. Instead of taking a callback it blocks until the result is 
// available. The browser will stay responsive during that time. 

var data = $.$getJSON("http://www.url.com/api/?callback=?", {data: "mydata"}); 
if (!data.length) { 
 // no results 
} else { 

 $(data).each(function(k, v){ 
    container.push(v.some_data); 
    }); 

 if (data.length < limit) { 
   var number_missing = limit - data.length; 
   // assuming your function 'myFunctionToGetSomethingElse' uses 
   // something like $.$getJSON inside, again you don't need a 
   // callback 
   $(myFunctionToGetSomethingElse(number_missing)).each(
     function(k, v){ 
     container.push(v.some_data); 
     }); 
     } 
} 

// console.log(container); 
// do something with the result. E.g. call returnFunction() or put the 
// code from returnFunction here directly 

,因爲你是第一個你可以在http://onilabs.com/apollo