Блокировка функции ожидания в JavaScript? - PullRequest
14 голосов
/ 09 ноября 2011

В рамках проекта Javascript, над которым я работаю, есть несколько синхронных вызовов ajax (я думаю, это делает его "sjax", но я отвлекся) . Сейчас я пишу панель отладки, которая позволила бы мне протестировать сайт с некоторыми искусственно смоделированными условиями сети, добавив $.ajax. Простые вещи: подделка ответа 500 и т. Д. И выполнение вызовов ajax занимает гораздо больше времени.

Для асинхронных вызовов это просто. Когда реальный ответ возвращается, добавьте setTimeout, чтобы заставить его ждать искусственного времени ответа, прежде чем вызвать обратный вызов. Однако это не работает с синхронными вызовами, очевидно, поскольку setTimeout не является синхронным.

Итак, есть ли способ заставить программу Javascript выполнять блокирующее ожидание в течение заданного промежутка времени?

Единственное, о чем я мог подумать, это что-то вроде этого:

function wait(ms) {
    var start = +(new Date());
    while (new Date() - start < ms);
}

Есть ли лучшее решение?

(Также, пожалуйста, предположите, что есть веская причина для блокировки вызовов ajax ... :-\)

Ответы [ 3 ]

5 голосов
/ 09 ноября 2011

Не делайте этого на уровне JavaScript. Получите прокси-сервер, например Fiddler , и настройте Автоответчик , чтобы задержать вызов на определенный период времени.

2 голосов
/ 09 ноября 2011

Если для целей отладки используется искусственная задержка:

alert('block me one more time');

Нет другого разумного подхода, чтобы иметь код блокировки в ECMAscript.Поскольку Javascript выполняется в том же потоке («поток пользовательского интерфейса»), который браузеры используют для визуализации DOM и некоторых других вещей, все шоу было разработано так, чтобы ничего не блокировать.

Конечно, вы можете подделать егоиспользуя цикл, но это извращение шоу.

0 голосов
/ 13 марта 2014

Я подумал, что этот код может помочь

// execute code consecutively with delays (blocking/non-blocking internally)
function timed_functions() 
{
    this.myfuncs = [];
    this.myfuncs_delays = []; // mirrors keys of myfuncs -- values stored are custom delays, or -1 for use default
    this.myfuncs_count = 0; // increment by 1 whenever we add a function
    this.myfuncs_prev   = -1; // previous index in array
    this.myfuncs_cur    = 0; // current index in array
    this.myfuncs_next  = 0; // next index in array
    this.delay_cur     = 0; // current delay in ms
    this.delay_default = 0; // default delay in ms
    this.loop = false;      // will this object continue to execute when at end of myfuncs array?
    this.finished = false;  // are we there yet?
    this.blocking = true;   // wait till code completes before firing timer?
    this.destroy = false;   // <advanced> destroy self when finished


    // handle next cycle execution
    this.next_cycle = function() {
        var that  = this;
        var mytimer = this.delay_default;

        if(this.myfuncs_cur > -1)
            if(this.myfuncs_delays[this.myfuncs_cur] > -1)
                mytimer = this.myfuncs_delays[this.myfuncs_cur];

        console.log("fnc:" + this.myfuncs_cur);
        console.log("timer:" + mytimer);
        console.log("custom delay:" + this.myfuncs_delays[this.myfuncs_cur]);

        setTimeout(function() {
        // times up! next cycle...
        that.cycle(); 

        }, mytimer);
    }



    this.cycle = function() {

        // now check how far we are along our queue.. is this the last function?
        if(this.myfuncs_next + 1 > this.myfuncs_count)
        {
            if(this.loop)
            {
                console.log('looping..');
                this.myfuncs_next = 0;
            }
            else
                this.finished = true;
        }


        // first check if object isn't finished
        if(this.finished)
        return false;

        // HANDLE NON BLOCKING //
        if(this.blocking != true) // blocking disabled
        {
            console.log("NOT BLOCKING");
            this.next_cycle();
        }


        // set prev = current, and current to next, and next to new next
        this.myfuncs_prev = this.myfuncs_cur;
        this.myfuncs_cur  = this.myfuncs_next;
        this.myfuncs_next++; 

        // execute current slot
        this.myfuncs[this.myfuncs_cur]();




        // HANDLE BLOCKING
        if(this.blocking == true)  // blocking enabled
        {
            console.log("BLOCKING");
            this.next_cycle();
        }

        return true;
    }; // END :: this.cycle





    // adders 
    this.add = {
        that:this,

        fnc: function(aFunction) { 
        // add to the function array
        var cur_key = this.that.myfuncs_count++;
        this.that.myfuncs[cur_key] = aFunction;
        // add to the delay reference array
        this.that.myfuncs_delays[cur_key] = -1;
        }
    }; // end::this.add




    // setters
    this.set = {
        that:this, 

        delay:          function(ms)    {  
            var cur_key = this.that.myfuncs_count - 1;
            // this will handle the custom delay array this.that.myfunc_delays
            // add a custom delay to your function container

            console.log("setting custom delay. key: "+ cur_key + " msecs: " + ms);
            if(cur_key > -1)
            { 
                this.that.myfuncs_delays[cur_key] = ms; 
            }

            // so now we create an entry on the delay variable
        },  // end :: this.set.delay(ms)

        delay_cur:      function(ms)        { this.that.delay_cur = ms;         },
        delay_default:  function(ms)        { this.that.delay_default = ms;         },
        loop_on:          function()        { this.that.loop = true; }, 
        loop_off:         function()        { this.that.loop = false; },
        blocking_on:      function()        { this.that.blocking = true; }, 
        blocking_off:     function()        { this.that.blocking = false; },

        finished:           function(aBool) { this.that.finished = true; }
    }; // end::this.set    




    // getters
    this.get = {
        that:this, 

        delay_default: function() { return this.that.delay_default; },
        delay_cur:     function() { return this.that.delay_cur; }
    }; // end::this.get     

} // end ::: timed_functions()

И проверить ...

// // // BEGIN :: TEST // // //

    // initialize
    var fncTimer = new timed_functions;

    // set some defaults
    fncTimer.set.delay_default(1000); // set a default delay between function blocks
    fncTimer.set.blocking_on(); // next timer begins count before code is executed
    fncTimer.set.blocking_off(); // next timer begins count after code is executed
    // fncTimer.set.loop_on(); // when finished start over
    // fncTimer.set.loop_off();


    // BEGIN :: ADD FUNCTIONS (they will fire off in order)
    fncTimer.add.fnc(function() {
        console.log('plan a (2 secs)');
    });
    fncTimer.set.delay(2000); // set custom delay for previously added function


    fncTimer.add.fnc(function() {
        console.log('hello world (delay 3 seconds)');
    });
    fncTimer.set.delay(3000);


    fncTimer.add.fnc(function() {
        console.log('wait 4 seconds...');
    });
    fncTimer.set.delay(4000);
    // END :: ADD FUNCTIONS


    // NOW RUN
    fncTimer.cycle(); // begin execution 


// // // END :: TEST // // //
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...