Pass in an array of Deferreds to $.when()

后端 未结 9 1194
伪装坚强ぢ
伪装坚强ぢ 2020-11-21 22:20

Here\'s an contrived example of what\'s going on: http://jsfiddle.net/adamjford/YNGcm/20/

HTML:

Click me!
&l
相关标签:
9条回答
  • 2020-11-21 22:48

    I had a case very similar where I was posting in an each loop and then setting the html markup in some fields from numbers received from the ajax. I then needed to do a sum of the (now-updated) values of these fields and place in a total field.

    Thus the problem was that I was trying to do a sum on all of the numbers but no data had arrived back yet from the async ajax calls. I needed to complete this functionality in a few functions to be able to reuse the code. My outer function awaits the data before I then go and do some stuff with the fully updated DOM.

        // 1st
        function Outer() {
            var deferreds = GetAllData();
    
            $.when.apply($, deferreds).done(function () {
                // now you can do whatever you want with the updated page
            });
        }
    
        // 2nd
        function GetAllData() {
            var deferreds = [];
            $('.calculatedField').each(function (data) {
                deferreds.push(GetIndividualData($(this)));
            });
            return deferreds;
        }
    
        // 3rd
        function GetIndividualData(item) {
            var def = new $.Deferred();
            $.post('@Url.Action("GetData")', function (data) {
                item.html(data.valueFromAjax);
                def.resolve(data);
            });
            return def;
        }
    
    0 讨论(0)
  • 2020-11-21 22:52

    To pass an array of values to any function that normally expects them to be separate parameters, use Function.prototype.apply, so in this case you need:

    $.when.apply($, my_array).then( ___ );
    

    See http://jsfiddle.net/YNGcm/21/

    In ES6, you can use the ... spread operator instead:

    $.when(...my_array).then( ___ );
    

    In either case, since it's unlikely that you'll known in advance how many formal parameters the .then handler will require, that handler would need to process the arguments array in order to retrieve the result of each promise.

    0 讨论(0)
  • 2020-11-21 22:54

    When calling multiple parallel AJAX calls, you have two options for handling the respective responses.

    1. Use Synchronous AJAX call/ one after another/ not recommended
    2. Use Promises' array and $.when which accepts promises and its callback .done gets called when all the promises are return successfully with respective responses.

    Example

    function ajaxRequest(capitalCity) {
       return $.ajax({
            url: 'https://restcountries.eu/rest/v1/capital/'+capitalCity,
            success: function(response) {
            },
            error: function(response) {
              console.log("Error")
            }
        });
    }
    $(function(){
       var capitalCities = ['Delhi', 'Beijing', 'Washington', 'Tokyo', 'London'];
       $('#capitals').text(capitalCities);
    
       function getCountryCapitals(){ //do multiple parallel ajax requests
          var promises = [];   
          for(var i=0,l=capitalCities.length; i<l; i++){
                var promise = ajaxRequest(capitalCities[i]);
                promises.push(promise);
          }
      
          $.when.apply($, promises)
            .done(fillCountryCapitals);
       }
      
       function fillCountryCapitals(){
            var countries = [];
            var responses = arguments;
            for(i in responses){
                console.dir(responses[i]);
                countries.push(responses[i][0][0].nativeName)
            }  
            $('#countries').text(countries);
       }
      
       getCountryCapitals()
    })
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div>
      <h4>Capital Cities : </h4> <span id="capitals"></span>
      <h4>Respective Country's Native Names : </h4> <span id="countries"></span>
    </div>

    0 讨论(0)
提交回复
热议问题