2016-04-07 20 views
1

我有一個簡單的服務方法,收集幾個.get(),我在「打印」部分有一些麻煩,因爲那時我只有一部分結果。如何鏈接方法才能在最後得到結果?

我在做什麼是:

var service = function() { 
    var players = []; // will hold 100 objects 

    var getMembers = function(id) { 
    $.get(url, function(data) { 
     for(i=0; i<data.length; i++) { 
     var p = data[i]; 
     // get more info for this member 
     getMemberDetails(p.member_id); 
     // put the current data into the players 
     players.push(p); 
     } 
    }); 

    calculateAndPrint(); 
    }; 

    var getMemberDetails = function(id) { 
    $.get(url, function(data) { 
     var result = $.grep(players, function(e){ return e.member_id == id; }); 
     if (result.length == 0) { /* not found */ } 
     else if (result.length == 1) { 
     // push new data to player object 
     result[0].details = data; 
     } 
    }); 
    }; 

    var calculateAndPrint = function() { 
    for(i=0; i<players.length; i++) { 
     var p = players[i]; 
     console.log(p); 
    } 
    }; 
})(); 

,這是不行的,因爲當我到達calculateAndPrint,該details甚至沒有設計尚未...

所以我嘗試$.Deferred()和我遇到的唯一問題是,如果我推遲getMemberDetails方法,該呼叫已包含一個deffer呼叫(.get()),我回到同一問題...

什麼是o全部打完100個電話後,都會運行calculateAndPrint

這似乎很容易,但我只是空白:/

+1

您可以遞增計數器,當它達到100時,在'getMemberDetails'回調中執行該函數 – Hacketo

+2

您確定要爲此數據發出100 + 1個http請求嗎?難道你不能批量所有的100個請求,以獲得詳細信息到一個電話? –

+0

你在哪裏使用ID以及如何調用'getMembers()'? – itzmukeshy7

回答

3

,如果您使用的承諾這應該是很容易的:

var service = function() { 
    var getMembers = function(id) { 
     return Promise.when($.get("some service url")) 
      .then(function (data) { 
       return Promise.all(data.map(getMemberDetails)); 
      }); 
    }; 

    var getMemberDetails = function(player) { 
     return Promise.when($.get("some service Url?id=" + player.member_id)); 
    }; 

    var calculateAndPrint = function(players) { 
     players.forEach(function (player) { 
      console.log(player); 
     }); 
    }; 

    return { 
     getMembers: getMembers, 
     calculateAndPrint: calculateAndPrint 
    }; 
})(); 

service.getMembers().then(function (players) { 
    service.calculateAndPrint(players); 
}); 
+0

darn ...爲什麼我要查找'$ .Deferred ()'而不是?並且把鏈放到外面是個好主意,我只是想調用'service.getMembers()'並立刻獲得所有內容:) – balexandre

-1

你可以只創建一個Deferred對象$.deferred每一個AJAX調用您的使&然後等待($.when)所有這些延期工作完成,然後再運行calculateAndPrint()方法。


如何使用:

  • 每一個Ajax調用$.deferred &回報的承諾對象.promise()創建一個延遲對象。
  • 取決於ajax調用是否成功,或者用響應數據.resolve(responseData)解析或者用錯誤數據.reject(errorData)拒絕。
  • 通過那裏監聽所有的ajax調用,並從那裏返回從第1步完成的對象,調用calculateAndPrint()方法。
  • 對於任意ajax調用,大部分上述邏輯保持不變,只是在for循環中調用這些邏輯,並且將這些延遲調用中的每一個都推送到deferredCalls數組中。

注:我建議表現出一定的裝載機/微調圖像時,您將AJAX調用,因爲你不會立即得到響應&保存用戶瞭解後臺操作始終是良好的用戶體驗的跡象。

JS代碼:

/* utils */ 
var $ul = $('ul'); 

function msg(text) { 
    $ul.append('<li>' + text + '</li>'); 
} 

/* functions */ 
function asyncThing1() { 
    var dfd = $.Deferred(); 
    setTimeout(function() { 
    msg('asyncThing1 seems to be done...'); 
    dfd.resolve('banana'); 
}, 1000); 
return dfd.promise(); 
} 

function asyncThing2() { 
    var dfd = $.Deferred(); 
    setTimeout(function() { 
    msg('asyncThing2 seems to be done...'); 
    dfd.resolve('apple'); 
    }, 500); 
    return dfd.promise(); 
} 

function asyncThing3() { 
    var dfd = $.Deferred(); 
    setTimeout(function() { 
    msg('asyncThing3 seems to be done...'); 
    dfd.resolve('orange'); 
    }, 1500); 
    return dfd.promise(); 
} 

/* do it */ 
$.when(asyncThing1(), asyncThing2(), asyncThing3()).done(function(res1, res2, res3) { 
    msg('all done!'); 
    msg(res1 + ', ' + res2 + ', ' + res3); 
}); 

Live Demo @ JSFiddle


任意延期調用Original SO Post

//Push all arbitrary ajax calls to deferred array 
var deferreds = []; 
function getSomeDeferredStuff() { 
    var i = 1; 
    for (i = 1; i <= 10; i++) { 
     var count = i; 
     deferreds.push(
     $.post('/echo/html/', { 
      html: "<p>Task #" + count + " complete.", 
      delay: count 
     }).success(function(data) { 
      $("div").append(data); 
     })); 
    } 
} 


// define a extension method for $.when for creating/managing deferred 
// objects for every ajax call 
if (jQuery.when.all===undefined) { 
    jQuery.when.all = function(deferreds) { 
     var deferred = new jQuery.Deferred(); 
     $.when.apply(jQuery, deferreds).then(
      function() { 
      var deferredObjs= function (arguments) { return deferreds.length > 1 ? $.makeArray(arguments) : [arguments]; } 
      deferred.resolve(deferredObjs); 
      }, 
      function() { 
      deferred.fail(deferredObjs); 
      }); 

     return deferred; 
    } 
} 

//passing the deferred calls array to $.when 
$.when.all(deferreds).then(function(objects) { 
    //process when all deferred objects compelted 
    console.log("Resolved/rejected objects:", objects); 
}); 

Working example for arbitrary ajax calls @JSFiddle

+0

OP的問題是關於在等待任意(即不是預定義的)數目的異步操作之後執行另一個異步操作。您的答案顯示瞭如何等待特定數量的並行操作,因此它不回答OP的問題。 – JLRishe

+0

好吧,這只是語法來做延遲調用,並在完成所有事情時得到通知。爲了進行任意延遲調用,必須在循環中創建一個延遲數組,然後將該延遲數組傳遞給'$ .when.apply' ,所以在進行任意延遲調用時,上面的解決方案沒有多大改變。只有更好地理解我纔會編輯答案。 – dreamweiver

相關問題