2016-02-27 4 views
0

Похоже, цикл for for зацикливает последний объект, обрабатываемый во всех полях.Почему мой цикл замерзает?

http://codepen.io/anon/pen/EKxNaN

Это фактический код, я использую, я построил что-то вроде похоже на codepen, так как я не могу запросить JSON от фактического источника на codepen.

var championMasteryPHP = "https://api.myjson.com/bins/xked"; 

$.getJSON(championMasteryPHP, function (json) { 
    for (var i = 0; i < json.length; i++) { 
     var champID = json[i].championId; 
     var champLevel = json[i].championLevel; 
     var pointstonextlevel = json[i].championPointsUntilNextLevel; 
     var championInfo = "http://example.com/champInfo.php?champid=" + champID; 

     $.getJSON(championInfo, function (json2) { 
      var champName = json2.name; 
      var champTitle = json2.title; 
      $('#champ').append("<li>ID: " + champID + " | Name: " + champName + " | Level: " + champLevel + " | Points to Next Level: " + pointstonextlevel + "</li>"); 
     }); 
    }; 
}); 

Короткий рассказ, что я пытаюсь достичь, будет выглядеть следующим образом.

image0

Но по какой-то причине, это то, что я получаю взамен.

image1

Правильные имена, но другие переменные являются самой последней переменной в списке.

Есть ли лучший способ сделать это? Я делаю что-то ужасно неправильно?

Спасибо.

+2

Я уверен, проблема в том, что у вас есть функция async внутри цикла for, и когда вызывается функция async, все ссылаются на одно и то же значение индекса. http://stackoverflow.com/questions/11488014/asynchronous-process-inside-a-javascript-for-loop –

+0

Возможный дубликат htt p: //stackoverflow.com/questions/11488014/asynchronous-process-inside-a-javascript-for-loop – JagsSparrow

+0

Это проблема «непонятного цикла». Позвольте мне опубликовать свой ответ –

ответ

2

Вы используете Асинхронный процесс внутри JavaScript для цикла more info here

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

var championMastery = "https://api.myjson.com/bins/xked"; 
$.getJSON(championMastery, function (json) { 
for (var i = 0; i < json.length; i++) { 

    (function(obj){ 
     var champID = obj.championId; 
     var champLevel = obj.championLevel; 
     var pointstonextlevel = obj.championPointsUntilNextLevel; 
     var championInfo = "http://example.com/champInfo.php?champid=" + champID; 

      $.getJSON(championInfo, function (json2) { 
       var champName = json2.name; 
       var champTitle = json2.title; 
       $('#champ').append("<li>ID: "+champID+" | Name: " +champName+ " | Level: " +champLevel+ " | Points to Next Level: " +pointstonextlevel+ "</li>"); 
      }); 
    })(json[i]) 
}; 
}); 
+0

Красивая! Казалось, что это проблема. Быстрый вопрос, хотя, Знаете ли вы, почему приложение не работает сейчас, когда оно отображается на странице? http://i.imgur.com/4X8K5Rt.png – Zlkva

+0

'$ .getJSON' - это асинхронная функция, поэтому' $ ('# champ'). append' будет зависеть от ответа сервера. Вы также можете проверить библиотеку [async] (https://github.com/caolan/async), чтобы облегчить проблему – JagsSparrow

1

Очень хорошая статья, которую я наткнулся в последнее время. Детальное описание Javascript Scope ans Closures. Это обязательная информация для кодирования в javascript, JQuery. И часть, где есть объяснение этой выше проблемы, - это поиск темы под Проблема печально известной петли

Теперь подходит к проблеме. Ваш код должен выглядеть так:

$.getJSON(championInfo, function (json2) { 
      (function(){ 
       var champName = json2.name; 
       var champTitle = json2.title; 
       $('#champ').append("<li>ID: "+champID+" | Name: " +champName+ " | Level: " +champLevel+ " | Points to Next Level: " +pointstonextlevel+ "</li>");    
      })() 
      }); 

Обратите внимание на изменение, в котором я добавил функцию самоиспускания. Проблема в том, что вы получили странный вывод с одинаковыми выходами для всей функции, потому что.

  • Ваша функция Внутри $.getJSON обратный вызов - это просто определение функции, и функция в этот момент не выполняется. К моменту, когда ваш первый getJSON перейдет на ваш вызов, цикл for завершен. И последнее значение в переменных относится к последнему циклу, и, следовательно, когда ваш первый getJSON достигает своего обратного вызова, он отображает значения последнего цикла.

Чтобы сделать его более простым. Напишите это в окне консоли.

function alert1(){ alert("I am one!!");} 

И теперь называем/выполнить функцию, делая

alert1(); 

Вы получите уведомление о том, «Я один !!"

Теперь добавьте в консоль

function alert1(){ alert("I am one, But overritten!!");} 

А потом попробовать называя его. Выездные путы будут:„Я один, но overritten !!“, поэтому функция фактически получает перезаписана и вот что происходит в цикле for. Последняя функция является той, которая доступна для всех обратных вызовов.

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