Javascript работает на одной ветке. Когда вы устанавливаете fn
для выполнения с интервалом, вы получаете доступ к DOM Api, который действует асинхронным образом (даже если он не является асинхронным). Что происходит, DOM api будет вставлять обратный вызов в очередь обратного вызова каждый раз, когда interval
является прошло. Итак, каждые 0 мс (ну, это на самом деле ближе к 4 мс, но это еще одна тема) fn
будет вставлен в очередь обратного вызова.
Теперь обратные вызовы в очереди обратного вызова только получить побежал, когда CallStack пуст, поэтому, обратный вызов не получает просуществовала до после
document.getElementById('out').innerHTML = this.foobar;
побежал, поэтому он выдает «Foo» вместо «бар».
http://jsfiddle.net/r0ueon53/13/
Если отложить эту линию на секунду, вы увидите, что выход «бар» вместо этого.
setTimeout(function() {
document.getElementById('out').innerHTML = that.foobar;
}, 1000);
http://jsfiddle.net/r0ueon53/12/
это работает, потому что setTimeout
вставит его обратный вызов в очередь обратного вызова 1 вторых позже, таким образом, после setInterval обратного вызова, который изменил значение «бар».
Очевидно, что при работе с AJAX, используя SetTimeout, чтобы исправить это не будет соответствовать из-за различий в скорости сети. Вместо этого вы должны просто переместить .innerHTML в обратный вызов, который вы передали на вызов ajax.
Не знаете, где «это» используется, поскольку оно не находится в коде, но узнайте о ['bind()'] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) – epascarello
'setInterval (fn, 0)' ждет завершения основного скрипта перед запуском 'fn', даже если время установлено на ноль. – JJJ
@epascarello 'this' здесь не проблема. Он правильно кэшируется с помощью 'this = this'. – JJJ