setTimeout в цикле для проверки изменения границ

Это мой код:

var b;
while(!b){
    setTimeout(function(){
        alert('sss')
        b=1;
    }, 500);
}

и он не будет предупреждать 'sss'

Что я могу сделать?

Обновлено:

Я хочу получить границы на картах Google v3:

function get_bounds(){
            var bounds_;
            while(!bounds_){
                setTimeout(function(){
                    bounds_=map.getBounds();
                    if(bounds_){
                        var leftBottom=[bounds_.getSouthWest().lat(),bounds_.getSouthWest().lng()]
                        var rightTop=[bounds_.getNorthEast().lat(),bounds_.getNorthEast().lng()]
                        return [leftBottom,rightTop];
                        }
                }, 500);
            }
        }

обновлено2:

привет патрик dw, я не знаю почему, но ваш код не работает:

var b;
function waitForB() {
    setTimeout(function(){
        if(!b)
            waitForB();
        else
            alert('sss');
    }, 500);
}
waitForB()

обновлено3:

сейчас нормально:

var b;
function waitForB() {
    setTimeout(function(){
        if(!b){
            waitForB();
            b='ss';
        }
        else{
            alert('sss')
        }
    }, 500);
}
waitForB()

person zjm1126    schedule 05.09.2010    source источник
comment
Вы забыли поставить точку с запятой после alert(...)   -  person Radomir Dopieralski    schedule 06.09.2010
comment
Да, это правда, но точка с запятой не всегда обязательна в Javascript.   -  person Pointy    schedule 06.09.2010
comment
@Radomir: благодаря JavaScript ; на самом деле не будет иметь значения. JS примет новую строку в качестве разделителя строки при отсутствии ; или не в блоке (...).   -  person Jeff Rupert    schedule 06.09.2010
comment
Если вы просто пытаетесь запускать код каждые 500ms, пока не получите bounds_, см. мой ответ ниже.   -  person user113716    schedule 06.09.2010


Ответы (4)


JavaScript в веб-браузерах выполняется в одном потоке. Когда вы вызываете setTimeout(), он не создает новый поток. Это означает, что setTimeout() не будет выполняться до тех пор, пока не завершится выполнение всего вашего основного кода.

По этой причине вы получите бесконечный цикл, потому что состояние вашего цикла зависит от выполнения обратного вызова setTimeout().

Вот интересная статья о том, как работают таймеры JavaScript:


ОБНОВЛЕНИЕ:

В дополнение к обновленному вопросу вы можете вместо этого прослушать событие bounds_changed. Я не уверен, как вы планируете использовать свою функцию get_bounds(), но вы можете реорганизовать свою логику, чтобы вместо этого использовать прослушиватель событий:

google.maps.event.addListener(map,'bounds_changed', function () {
   // The code here is triggered when the bounds change
});
person Daniel Vassallo    schedule 05.09.2010
comment
привет, Дэниел, посмотри на обновление, я хочу получить границы карт Google v3, но иногда я не могу его получить, поэтому иногда мне приходится получать его позже, так что я могу с этим поделать .. - person zjm1126; 06.09.2010
comment
@zjm1126: Почему ты не слушаешь событие bounds_changed? google.maps.event.addListener(map,'bounds_changed', function () { }); - person Daniel Vassallo; 06.09.2010
comment
Можете ли вы резюмировать интересную связанную статью в своем ответе? Это защищает идеи от гниения ссылок. - person Iain Samuel McLean Elder; 15.11.2013

Этот код будет сжигать процессорное время и память, планируя тайм-ауты. Подумайте об этом: ваше условие цикла - "b" становится правдой. Как это произойдет? Только когда срабатывает событие таймера. Это произойдет? Нет, потому что вы съедаете всю машину, планируя миллионы тайм-аутов.

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

Я не знаю, какой эффект вы пытаетесь получить. Почему бы не начать с просто вызова setTimeout() и посмотреть, что получится. Может быть, вы могли бы подробнее описать, что вы пытаетесь сделать.

person Pointy    schedule 05.09.2010

Возможно, вы захотите использовать setInterval вместо setTimeout. При изменении b появляется предупреждение.

var b = false;
(function () {
    var intervalId;
    function wait() {
        if (b) {
            clearInterval(intervalId);
            alert('sss');
        }
    }
    intervalId = setInterval(wait, 500);
})();

Это более интуитивно понятно и не слишком сильно влияет на глобальные переменные.

СОВЕТ: Ставьте точку с запятой после каждого оператора, если вы не уверены, где безопасно пропустить.

person pepkin88    schedule 05.09.2010

Теперь эту проблему можно решить правильно, используя прослушиватель событий idle, а не bounds_changed:

google.maps.event.addListener(map, 'idle', function() { 
  updateStuff();
});

Это событие запускается, когда карта становится бездействующей после панорамирования или масштабирования. http://code.google.com/apis/maps/documentation/javascript/reference.html

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

person thomax    schedule 21.01.2011