Как реорганизовать код javascript, когда требуется функциональность в режиме ожидания?

#javascript #ajax #refactoring #sleep

#javascript #ajax #рефакторинг #sleep

Вопрос:

Я вижу, что в SO есть много тем, в которых запрашивается функция sleep в javascript, и я знаю, что это можно сделать только с помощью setTimeout и setInterval .

Я произвел некоторые пользовательские скрипты с помощью greasemonkey и написал скрипт, который загружает много страниц и что-то вычисляет на их основе. Это работает, но я не хочу запрашивать страницы слишком быстро.

 var html0=syncGet(url0); // custom function for sync ajax call.
// fill the something array
for(var i=0;i<something.length;i  )
{
   // calculate url1,url2 using the array and the i variable
   // do something with lots of local variables
   var html1=syncGet(url1);
   // I would put a sleep here.
   // do something with the results
   var html2=syncGet(url2);
   // I would put a sleep here.
   // do something with the results
   // get url3 from the page loaded from url2
   var html3=syncGet(url3);
   // I would put a sleep here.
   // do something with the results
}
// use the result of the for loop and lots of code will follow...
  

Фактический код немного сложнее и длиннее этого.

Я плачу из-за несуществующей функции sleep (и понимаю, почему это невозможно) Как реорганизовать это, чтобы использовать функции setTimeout, setInterval и сохранить его читаемым (и работающим)?

Ответ №1:

Например, это:

 var urls = ["your","u","r","l´s"];
var htmls = new Array(urls.length);
var time = 1000;
for(var i=0;i<urls.length;i  ){
    (function(i){
        setTimeout(function(){
            htmls[i] = syncGet(urls[i]);
            if(i == urls.length-1){
                //continue here
            }
        },time*i);
    })(i);
}
  

Ответ №2:

У меня была похожая проблема, когда большой цикл блокировал весь браузер в некоторых старых браузерах, я решил ее с помощью :

 function handlenext(idx,length) {
    idx  

    //do your stuff here base on idx.


    if (idx < length) {
        setTimeout(function(){handlenext(idx,length)},1)
    } else {
        initSuccessEnd()
    }
}

var ln = something.length;


if (ln>0) {
    handlenext(0,ln);
} else {
    initSuccessEnd()
}
  

здесь initSuccessEnd — это функция обратного вызова, вызываемая, когда все завершено..

Ответ №3:

После исследования я думаю, что новый итератор-генератор от Mozilla может быть наиболее подходящим. (Поддерживается начиная с FF2)

 function doSomething()
{
   //.....
      var html=syncGet(url1);
      yield true;
      var html2=syncGet(url2);
      yield true;
      var html3=syncGet(url3);
      yield true;
   //......
   yield false;
}

function iteratorRunner(iterator,timeout)
{
    if (iterator.next()) 
    {
       setTimeout(function(){iteratorRunner(iterator,timeout)},timeout);
    }
    else
    {
       iterator.close();
    }
}

var iterator=doSomething(); // returns an iterator immediately
iteratorRunner(iterator,1000); // runs the iterator and sleeps 1 second on every yield.
  

Я надеюсь, что greasemonkey справится с этим…

Комментарии:

1. Greasemonkey не может справиться с этим … пффф