2017-01-20 2 views
0

У меня есть данные, как показано ниже, и два цикла javascript и ajax для получения данных. Эти две петли корректно работают с значениями i j. Но если я добавлю ajax во внутренний цикл, запросы не будут проходить последовательно. Мне нужны данные, которые нужно получить в последовательности циклов. Как мы можем достичь этого?Закрытие скрипта java для асинхронных вызовов ajax

var final = {}; 
final.reports = ['a','b','c'] 
final.clients = ['x','y'] 
final.reportDataJson = []; 

for(var i=0;i<final.reports.length;i++){ 
     (function(i,reactthis){ 

      for(var j=0;j<final.clients.length;j++){ 
       (function(i,j,final){ 
        console.log(i+" "+j+" "+final.clients[j]) 
        // this shows correct i j values 
        $.ajax({ 
         url: url, 
         cache: false, 
         success: function(html) { 
          var reportResponse = { 
           reportname : final.reports[i], 
           clientname : final.clients[j], 
           reporthtml : html, 
           reportgraph : '' 
          } 
          final.reportDataJson.push(reportResponse) 
          //console.log(i,j) 
          if(i == final.reports.length-1 && j == final.clients.length-1){ 

           console.log(final.reportDataJson); 

          } 
         }, 
         error: function(xhr, status, err) { 
          if(i == final.reports.length-1 && j == final.clients.length-1){ 
          } 
         } 
        })    

       }) 
      } 


     })(i,final); 
    } 
+0

'// это показывает правильный IJ values' - Сомневаюсь, код там не побежит –

+0

' $ .ajax' является асинхронным, и нет никакой гарантии, что порядок, в котором они выполняются, будет в порядке, в котором они заканчиваются, поэтому 'if (i == final.reports.length-1 && j == final.clients.length-1) {' не гарантирует, что все данные были получены для начала, и, конечно, порядок, вероятно, будет неправильным ... посмотрите на '$ .when' для решения –

ответ

0

Вы можете использовать тот факт, что $.ajax возвращает обещание - с $.when - что ждет ряд посылов и возвращает разрешенные значения в порядке!

var final = {}; 
final.reports = ['a', 'b', 'c']; 
final.clients = ['x', 'y']; 
final.reportDataJson = []; 

$.when.apply($, [].concat.apply([], final.reports.map(function(report) { 
    return final.clients.map(function(client) { 
     return $.ajax({ 
      url: url, 
      cache: false 
     }).then(function(results) { 
      var html = results[0]; 
      // results[0] is same as success: html argument 
      // results[1] is textStatus 
      // results[2] is jqXHR 
      return { 
       reportname: report, 
       clientname: client, 
       reporthtml: html, 
       reportgraph: '' 
      }; 
     }); 
    }) 
}))).then(function() { 
    final.reportDataJson = [].slice.call(arguments); 
    console.log(final.reportDataJson); 
}); 

использование $ .when.apply, потому что $ .when принимает аргументы 1..n, как обещания

использование [] .concat.apply к "придавить" массив массивов, возвращаемых вложенной. МАП

Это немного проще с родной Promise

Promise.all([].concat.apply([], final.reports.map(function(report) { 
    // code unchanged from above .... 
}))).then(function(results) { 
    final.reportDataJson = results; 
    console.log(final.reportDataJson); 
}); 

Promise.all принимает массив обещаний, и это .then обратного вызова принимает один аргумент, массив результата с тех обещаний

И ради ES2015 + благости

Promise.all([].concat.apply([], final.reports.map(report => final.clients.map(client => $.ajax({ 
    url: url, 
    cache: false 
}).then(([html, status, jqXHR]) => ({ 
    reportname: report, 
    clientname: client, 
    reporthtml: html, 
    reportgraph: '' 
})))))).then(results => console.log(final.reportDataJson = results)); 
Смежные вопросы