Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Задержка выполнения кода в рекурсии  (Прочитано 10592 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« : 27-01-2013 20:13 » 

Существует некая коллекция
и функция по работе с ней.
Каждый элемент может быть  простым, или также быть коллекцией.

Код:
var a=[1,['a',[10,20,30],'b'],3,4];

Код:
function whatAmI(me){ return Object.prototype.toString.call(me).split(/\W/)[2]; } //Это способ получения типа элемента js

function t_log(collect, collect_index){
if (collect_index < collect.length) {
console.log(collect[collect_index]);
if (whatAmI(collect[collect_index]) === "Array"){

type_log(collec,collect_index)
//Вот здесь нужно остановиться и ждать пока не выполнится  type_log, а вернее задержаная функция
/***********************************
*Точка остановки
***********************************/


t_log(collect[collect_index],0);
}
collect_index++;
t_log(collect, collect_index);


}
};

function type_log(collec,collect_index){
inter = setInterval(somefunction, 50)
}

t_log(a,0);

Т.е. проще нет, и быть не может - рекурсия.

Но как оказалось, что нужно  остановиться и ждать в Точке остановки.

Каких либо функций тип sleep, delay не существует

Конструкция while flag {}  со сбросом/установкой флага в "задержанной" функции (somefunction) вешает браузер.


И что делать?






Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 27-01-2013 21:25 » 

Для чего нужна задержка? JS однопоточный.

Цитата
Код: (Javascript)
type_log(collec,collect_index)
Опечатка? Переменной collec не видно.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
zubr
Гость
« Ответ #2 : 28-01-2013 04:04 » 

А window.setTimeout ?
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 28-01-2013 06:30 » 

Думаю, если хранить контекст в некоторой глобальной переменной, можно организовать вычисления на таймере.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 28-01-2013 08:00 » 

Sla, сделать функцию частью объекта - поместить в замыкание; разбить на 2 функции: до остановки, в конце вызов setTimeout, и после остановки - обработчик таймера. collect и collect_index - переменные объекта, их - из параметров наружу в замыкание.

P.S. Только для вызывающей программы придётся callback продолжения делать. Сам-то setTimeout поток не останавливает, а лишь ставит в очередь на исполнение кусок кода - после таймаута и освобождения движка от текущего исполненения кода.
« Последнее редактирование: 28-01-2013 08:13 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 28-01-2013 09:24 » 

Цитата
Опечатка? Переменной collec не видно
Да, просто писал сразу в тему


Цитата
А window.setTimeout ?
Оно так и есть, в примере не показано

Цитата
сделать функцию частью объекта - поместить в замыкание; разбить на 2 функции: до остановки, в конце вызов setTimeout, и после остановки - обработчик таймера. collect и collect_index - переменные объекта, их - из параметров наружу в замыкание.

Думал над этим...
Но я пока не представляю как это организовать. Вернее - как запомнить состояние дерева.
Можно, хотя бы на "пальцах"?








Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 28-01-2013 10:29 » 

Приблизительно. Могу ошибиться в синтаксисе.

Код: (Javascript)
function Task() {
    return {
        collect: null,
        collect_index: null,
        start: function (collect, collect_index) {
            this.collect = collect;
            this.collect_index = collect_index;
            this.continue();
        },
        continue: function () {
            collect = this.collect;
            collect_index = this.collect_index;
            if (collect_index < collect.length) {
                console.log(collect[collect_index]);
                if (whatAmI(collect[collect_index]) === "Array") {
                    type_log(collec,collect_index);
                    this.start(collect[collect_index], 0);
                }
                collect_index++;
                this.start(collect, collect_index);
            }
            this.collect = collect;
            this.collect_index = collect_index;
            setTimeout(this.continue, 50);
        };
};

Task().start(a, 0);
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 28-01-2013 12:15 » 

Код: (HTML)
<SCRIPT type="text/javascript">

  // Просто рекурсия.
  function fac(n) {
    return n == 0 ? 1 : n * fac(n - 1);
  }

  // Рекурсия с асинхронными прерываниями.
  function fac_int(n, callback) {
    if(n == 0) {
      callback(1);
    } else {
      window.setTimeout(
        function() {
          fac_int(
            n - 1,
            function(f) {
              callback(n * f);
            }
          )
        },
        1000
      );
    }
  }

  window.onload = function() {
    alert(fac(6));
   
    fac_int(
      6,
      function(f) {
        alert(f);
      }
    );
  }

</SCRIPT>
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #8 : 29-01-2013 10:20 » 

Dimka,

Все классно
Но... это решение не требует возврата к корню дерева.

по сути это задержка вычисления

В моем случае нужно запоминать состояние дерева.

т.е. вызывается
type_log(collect,collect_index)
в котором есть запуск вычислений по таймеру


Или я, наверное, туплю...
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 29-01-2013 12:18 » 

Sla, не очень понятно.

Код: (Javascript)
  // Рекурсивная обработка массива.
  function go_array(array, index) {
    if(index >= array.length) {
      // Выход из рекурсии.
      return;
    } else {
      // Тут надо сделать паузу, а потом продолжим.
      window.setTimeout(
        function() {
          // Идём в глубину.
          go(array[index]);
          // Идём в ширину.
          go_array(array, index + 1);
          // Потенциально это даёт развилку, т.е. может быть
          // установлено 2 таймаута, заканчивающихся
          // примерно одновременно. И количество параллельных
          // таймаутов будет расти по мере расширения обхода.
        },
        1000
      );
    }
  }

  // Обработка любого элемента.
  function go(object) {
    if(object instanceof Array) {
      // Массив - нужно обойти, запускаем рекурсию.
      go_array(object, 0);
    } else {
      // Атомарный элемент - выводим.
      alert(String(object));
    }
  }

  window.onload = function() {
    go([1, 2, [31, 32], 4]);
  }

Вот решение без возвратов и без накопления замыканий в памяти: всё заканчивается alert'ом атомарного элемента. Но здесь же присутствует асинхронность обхода дерева и такой эффект псевдо-параллелизма. Т.е. некие действия по таймауту происходят не строго последовательно, а с разрастанием числа параллельных таймеров. Последовательную обработку их событий - диспетчеризацию - осуществляет движок JavaScript.

Оно работает так: 1 - пауза - 2 - пауза - 31, 4 (параллельные ветки fork) - пауза - 32.

Если тебе последовательно надо, тогда надо запоминать один из путей, чтобы потом (закончив в ширину или глубину) вернуться к нему (к глубине или ширине соответственно) - иначе никак.
« Последнее редактирование: 29-01-2013 12:20 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines