使用回调函数和异步请求时避免重复

时间:2010-09-22 11:01:21

标签: javascript jquery refactoring callback

我正在编写一些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);
        }
    }
});

您如何建议我避免重复回调中的代码?这是唯一可能的方式吗?

3 个答案:

答案 0 :(得分: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

的更多信息

答案 1 :(得分:1)

有一个图书馆提供“分层的javascript”。奇怪的是,它将异步调用包装成顺序范例。回到原点:)

看看oni labs

答案 2 :(得分: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,这绝对有信心。