2015-11-09 6 views
0

У меня есть функция JQueryВозвращение обещание рекурсивной Jquery AJAX

group: function (text) { 
     var a1 = SPM.aChart(); 
     var a2 = SPM.aSChart(); 
     $.when(a1, a2).done(function() {//excecutes below function when all the charts are loaded. 
      SPM.EIEachGroup(); 
     }); 
    }, 

aChart и aSChart загружает несколько графиков и после загрузки все, что нужно вызвать EIEachGroup функция(), эти две функции рекурсивные функции AJAX, в настоящее время Функция EIEachGroup() запускается, когда диаграммы не загружаются, вот как я возвращаю обещание от вызова ajax.

aChart: function() { 
     var grpAttrId = 1; 
     var group = 'a'; 
     var def = $.Deferred(); 
     return $.ajax({ 
      url: Url.getSegmentBreak, 
      type: 'GET', 
      data: { sgmntGrpAttrId: grpAttrId, selectedGroup: group }, 
      dataType: 'json', 
      success: function (data) { 
       jQuery.each(data, function (index, item) { 
        $.ajax({ 
         url: Url.GetScatterPlot, 
         type: 'GET', 
         data: { sgmntGrpAttrId: grpAttrId, selectedGroup: group, segmentBreak: item }, 
         dataType: 'json', 
         success: function (data) { 

          SPM.GetSegmentScatterPlot(data,item);//function to plot chart 
         } 
        }); 
       }); 

      } 
     }); 
     def.resolve(); 
     return def.promise(); 
    }, 

aSChart также похож выше AJAX, какие изменения необходимо сделать, чтобы EIEachGroup() вызывается, когда обе эти функции полностью сделано.

--update - изменили функцию как упоминалось выше, но все равно это не будет ждать, пока он закончит, ниже это изменение я сделал

aMultiAxesChart: function() { 
     var grpAttrId = 1 
     var group = 'a' 
     var def = $.Deferred(); 
     return $.ajax({ 
      url: Url.getSegmentBreak, 
      type: 'GET', 
      async: false, 
      data: { sgmntGrpAttrId: grpAttrId, selectedGroup: group }, 
      dataType: 'json' 

     }).done(function (data) { 
      var calls = jQuery.map(data, function (item, index) { 
       return $.ajax({ 
        url: Url.GetHistMedTransData, 
        type: 'GET', 
        data: { 
         sgmntGrpAttrId: grpAttrId, selectedGroup: group, segmentBreak: item 
        }, 
        dataType: 'json', 
        success: function (data) { 
         var seriesData = []; 
         var seriesData1 = []; 
         var seriesData2 = []; 
         var xCategories = []; 

         for (i = 0; i < data.length; i++) { 
          if (seriesData) { 

           var segName = data[i].MnthSmryStartDate; 
           if (xCategories.indexOf(segName) === -1) { 
            xCategories[xCategories.length] = segName; 
           } 
           seriesData1[i] = data[i].MedianTransactionAmt; 
           seriesData2[i] = data[i].MedianTransactionCnt; 
          } 
         } 
         seriesData = [ 
         { 
          name: 'Amount', 
          type: 'column', 
          color: '#808080', 
          data: seriesData1, 
          tooltip: { 
           valueSuffix: ' mm' 
          } 

         }, { 
          name: 'Count', 
          type: 'line', 
          color: 'Red', 
          yAxis: 1, 
          data: seriesData2, 
          tooltip: { 
           valueSuffix: ' °C' 
          } 
         } 
         ]; 
         var divIndex = 1 + index; 
         var name = '#dvHistMed1' + divIndex; 
         SegmentProgressMeter.GetSegmentHistMedTransData(xCategories, seriesData, item, name); 
        } 
       }); 
      }); 
      return $.when.apply($, calls); 
     }).promise(); 
    }, 
+1

Вы знаете, что используете 'return' дважды? 'return $ .ajax ({' и 'return def.promise();' so second unreachable – Grundy

+0

@ Grundy- следует удалить return $ .ajax и сохранить return def.promise()? –

+0

@crowder - я сделал изменение как вы предложили, но все равно это не подождало, я разместил код, вы видите какие-либо изменения? –

ответ

0
var arr = []; 
$.each(arr, function(i, v) { 
var url = '/xml.php?id=' + v; 
var xhr = $.ajax({ 
    url: url, 
    type: 'GET', 
    dataType: 'xml', 
    success: function(xml) { 
     if ($(xml).find('Lists').attr('total') == 1) { 
      // some code here 
     } 
    }, 
    complete: function() { 
     // some code here 
    } 
}); 
arr.push(xhr); 
}) 

$.when.apply($, arr).then(function(){ 
console.log('done') 
}) 
1

Как Гранди отметил, вы не создавая Deferred вы никогда использовать. Это нормально, вам ничего не нужно   — Создание нового обещания, когда у вас уже есть обещание работать с анти-шаблоном.

Смотреть код комментарии:

aChart: function() { 
    var grpAttrId = 1; 
    var group = 'a'; 
    // Return the promise we get from the deferred we get from calling 
    // `done` on the first ajax call 
    return $.ajax({ 
     url: Url.getSegmentBreak, 
     type: 'GET', 
     data: { sgmntGrpAttrId: grpAttrId, selectedGroup: group }, 
     dataType: 'json' 
    }).done(function(data) { 
     // First call is complete, get promises for all the subordinate parallel calls 
     var calls = jQuery.map(data, function (item) { // Note that jQuery.map doesn't give you the index first 
      // Return the promise here; these will be collected into 
      // an array by jQuery.map 
      return $.ajax({ 
       url: Url.GetScatterPlot, 
       type: 'GET', 
       data: { sgmntGrpAttrId: grpAttrId, selectedGroup: group, segmentBreak: item }, 
       dataType: 'json', 
       success: function (data) { 

        SPM.GetSegmentScatterPlot(data,item);//function to plot chart 
       } 
      }); 
     }); 

     // Return a promise that waits on all of them (syntax is a bit strange, I know) 
     return $.when.apply($, calls); 
    }).promise(); // `done` returns Deferred, but we only want to return the Promise 
}, 

Ключ к вышесказанному, и работать с обещаниями в целом, является то, что при вызове then (или done, который является своего рода-псевдонима для then на JQuery-х Deferred), возвращаемое значение - новое обещание (назовем его NewPromise). NewPromise будет ждать обещанного вами обещания then, затем позвоните обратному вызову, который вы дали done, и если , что возвращает обещание, NewPromise ждет на нем; если обратный вызов не возвращает обещание, NewPromise сам решает использовать возвращаемое значение в качестве разрешения.

Итак:

return $.ajax(...).done(function() { 
    return somePromise; 
}); 

... даст вам обещание, что будет ждать не только для вызова Ajax, но и за обещание возвращенного done обратного вызова.

Это большая часть возможностей обещаний.

Причина сильного синтаксиса $.when заключается в том, что $.when ожидает получить отдельные аргументы обещания и ждать их всех; он не принимает массив. К счастью, JavaScript имеет Function#apply, который мы можем использовать для вызова функции с массивом аргументов, чтобы функция рассматривала их как дискретные аргументы. Итак, $.when.apply($, calls) (первый аргумент apply - это то, что следует использовать как this во время разговора). В ES2015 мы могли бы использовать $.when(...calls), но ES5 не имеет оператора спреда.

+0

действительно нужно 'when.apply '?мы можем передать только массив? – Grundy

+1

@Grundy: Мы действительно не можем просто передать массив. Сумасшедший, не так ли? Вместо этого я использую 'whenAll' (если я использую jQuery-обещания в ES5 - если использовать jQuery-обещания в ES2015, я просто делаю' $ .when (... theArray) ', но ES5 не имеет спред оператора). –

+0

странно :-) почему бы не добавить это – Grundy

Смежные вопросы