Как реорганизовать код javascript, когда требуется сон, как требуется функциональность? - PullRequest
2 голосов
/ 29 апреля 2011

Я вижу, что в SO много потоков о запросе функции сна 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...

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

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

Ответы [ 3 ]

2 голосов
/ 29 апреля 2011

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

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);
}
1 голос
/ 29 апреля 2011

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

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 - это функция обратного вызова, вызываемая, когда все закончено ..1004 *

0 голосов
/ 30 апреля 2011

После исследования я думаю, что новый материал итератора-генератора 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.

Надеюсь, что салазка справится с этим ...

...