2013-11-22 8 views
1

Я пытаюсь сломать для цикла (с маркировкой) во вложенном анонимной функции, например:Перерыв на цикл из анонимной функции

function ajax(iteration, callback) { 
    var rtrn, xh; 
    if (window.XMLHttpRequest) { 
     xh = new XMLHttpRequest(); 
    } else { 
     xh = new ActiveXObject("Microsoft.XMLHTTP"); 
    }; 
    xh.onreadystatechange = function() { 
     if (xh.readyState == 4 && xh.status == 200) { 
      callback(xh.responseText); 
     }; 
    }; 
    xh.open("GET", "file.php?i=" + iteration, true); 
    xh.send(); 
}; 

var atk_delay = 100; 
loop: 
for(i = 1; i <= 40; i++) { 
    var to = atk_delay * i; 
    setTimeout(
     function() { 
      ajax(i, function(responseText) { 
       var div = document.getElementById("combat"); 
       div.innerHTML += responseText; 
       var arrRt = responseText.split("::"); 
       if(arrRt[0] == "stop") { 
        break loop; 
       }; 
      }); 
     }, 
    to); 
}; 

Я действительно понятия не имею, как решить это. Очевидно, проблема заключается в том, что он не может найти метку. Как я могу это решить?

+0

Я отредактировал вопрос, так как на этикетке было неправильное имя. Теперь код такой, какой у меня есть. –

+4

Знаете ли вы, что когда вы дойдете до точки, где хотите ее разбить, цикл уже остановился? – kapa

+0

'setTimeout' и' ajax', очевидно, асинхронны, логика внутри обратного вызова возникает после завершения цикла, а 'i' теряется из-за новой области. Таким образом, здесь есть две проблемы: [«Проблемная ошибка JavaScript»] (http://stackoverflow.com/questions/1451009/javascript-infamous-loop-problem) и [«Как вернуть ответ от вызова AJAX "] (http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call) – elclanrs

ответ

0

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

Однако в вашем конкретном случае, поскольку вы вызываете setTimeout, выполнение цикла может быть завершено к тому моменту, когда вы даже можете установить значение. setTimeout назначает функцию для последующего выполнения (в мс).

Вы можете использовать переменную для выхода из анонимной функции раньше, если что-то пометило ее как выполненную.

+0

Я только что понял это. Я честно пропустил это полностью. Я виню поздний час здесь, в Швеции. Может, вместо этого я мог бы использовать рекурсивную функцию? –

+0

Это будет хорошо работать; вы не можете выполнить следующий шаг на всех, а не пытаться сломать при необходимости. – Travis

+0

Я отправил свое решение как anwer! Спасибо за ваше время и помощь! :-) –

1

Так что я решил это! Спасибо за помощь, ребята! Вы поняли, что мне нужен совершенно другой подход!

function ajax(callback) { 
    var rtrn, xh; 
    if (window.XMLHttpRequest) { 
     xh = new XMLHttpRequest(); 
    } else { 
     xh = new ActiveXObject("Microsoft.XMLHTTP"); 
    }; 
    xh.onreadystatechange = function() { 
     if (xh.readyState == 4 && xh.status == 200) { 
      callback(xh.responseText); 
     }; 
    }; 
    xh.open("GET", "file.php", true); 
    xh.send(); 
}; 

var atk_delay = 100; 

function roll() { 
    ajax(function(responseText) { 
     var div = document.getElementById("combat"); 
     div.innerHTML += responseText; 
     var arrRt = responseText.split("::"); 
     if(arrRt[0] == "cont") { 
      setTimeout(roll, atk_delay); 
     }; 
    }); 
}; 

setTimeout(roll, atk_delay); 
+0

[Никогда не передавать строку в 'setTimeout'] (https://developer.mozilla.org/en/docs/Web/API/window.setTimeout#Passing_string_literals) - это то же самое, что вызывать на ней' eval' , со всеми проблемами, которые он приносит в таблицу. Всегда используйте ссылку на функцию, например 'setTimeout (roll, atk_delay);'. – kapa

+0

О, я понятия не имел! Благодаря! –

0

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

function foo().then(s => { 
    ... some code 
    debugger // here your code will break. 
    someVariableIwantToExamine 
} 
Смежные вопросы