|
Как сделать рекурсивную функцию с ожиданием? | ☑ | ||
---|---|---|---|---|
0
Помогите
16.10.13
✎
12:09
|
Нужно чтобы внутри функции было ожидание события. Как это сделать?
Например такая функция: function next(i){ a.load(i); //тут нужно подождать a.onload next(i+1); } |
|||
1
Помогите
16.10.13
✎
12:10
|
javascript
|
|||
2
Eugene_life
16.10.13
✎
12:15
|
А цикл не подойдет для этого?
|
|||
3
Помогите
16.10.13
✎
12:34
|
(2) если только в цикле можно будет как-то сделать ожидание события a.onload
|
|||
4
Eugene_life
16.10.13
✎
12:35
|
джавой я не владею, так что кроме идеи ничем не смогу помочь.
|
|||
5
Помогите
16.10.13
✎
12:41
|
жаль
|
|||
6
smaharbA
16.10.13
✎
12:42
|
a.onload=function(){alert(123)}
a - это чего ? |
|||
7
Kreont
16.10.13
✎
12:44
|
посмотри в сторону jquery, там готовые методы есть, тем более если javascript знаешь то быстро разберешся
|
|||
8
Помогите
16.10.13
✎
12:56
|
(6) гуд.
а - какой-то абстрактный объект, событие которого нужно ждать |
|||
9
Помогите
16.10.13
✎
13:01
|
function next(i){
a.load(i); a.onload=function(){next(i+1);} } |
|||
10
Помогите
16.10.13
✎
13:01
|
Спасибо!
Осталось разобраться почему не всегда срабатывает... |
|||
11
Asmody
16.10.13
✎
13:03
|
(9) строки местами поменяй
|
|||
12
Лефмихалыч
16.10.13
✎
13:08
|
jscript - это грёбаное вуду...
|
|||
13
Помогите
16.10.13
✎
13:24
|
(11) у меня и было наоборот в рабочей программе.
|
|||
14
NS
16.10.13
✎
13:26
|
(4) Это не java.
|
|||
15
Rie
16.10.13
✎
13:26
|
(0) Дык, как уже было верно замечено выше, это - хвостовая рекурсия, то бишь, цикл во всей его красе.
Но вопрос - зачем ждать в цикле? Тебе две функции надо: первая - инициализировать, вторая - обработать событие. |
|||
16
y88
16.10.13
✎
13:29
|
setTimeout(Function, Delay);
|
|||
17
Asmody
16.10.13
✎
13:31
|
тут еще очень интересна природа объекта a, ибо в варианте (0) a - глобальный объект, так что переназначать в рекурсии обработчик особого смысла не имеет.
|
|||
18
Помогите
16.10.13
✎
13:44
|
(17) как тогда передать параметры в функцию обработчика если не переназначать ее?
|
|||
19
NS
16.10.13
✎
13:52
|
(18) Зачем передавать? Делаешь i глобальной переменной, и при обработке увеличиваешь на единицу.
|
|||
20
Rie
16.10.13
✎
13:53
|
(18) Классная штука - closure.
|
|||
21
uno-group
16.10.13
✎
14:00
|
ИМХо в 7 ябы делал като так.
ОброботкаОжидания("a.load",10)//10 секунд ожидания. А И делать глобальной переменной иувеличивать по на добности. без всяких скриптов. |
|||
22
Asmody
16.10.13
✎
14:01
|
(18) а тут многое от задачи зависит
|
|||
23
Asmody
16.10.13
✎
14:02
|
(19) и что? мы же не можем гарантировать порядок наступления событий
|
|||
24
NS
16.10.13
✎
14:13
|
(23) Не понял. Что ты имеешь в виду?
|
|||
25
NS
16.10.13
✎
14:15
|
function next(){
a.load(i); i=i+1; } a.onload=function(){next();} |
|||
26
Asmody
16.10.13
✎
14:46
|
(25) так это не совсем то, что в (0)
|
|||
27
NS
16.10.13
✎
14:48
|
(26) Это копия того что в (0)
|
|||
28
Asmody
16.10.13
✎
14:51
|
(27) да ладно!
|
|||
29
Asmody
16.10.13
✎
14:51
|
может по старинке по шагам пройтись?
|
|||
30
NS
16.10.13
✎
14:55
|
в (0) a.load(i);
Нужно подождать onload, и запустить с i=i+1. в (25) Ровно тоже самое. (29) Давай. Запускаем. i=1; Next(); Выполняется a.load(1);i=i+1 (i=2) ждет onload. после этого запускается Next(); a.load(2);i=i+1 (i=3) ждет onload. после этого запускается Next(); a.load(3);i=i+1 (i=4) и т.д. |
|||
31
Помогите
17.10.13
✎
06:10
|
Как бы это все не то. Потому что нет возврата в вызывающую функцию из дочерней функции. Получается не рекурсия, а линейный вызов.
Задача вообще такая: Пробежаться по дереву каталогов, и загрузить все найденные файлы. Условно "a.load(i)" - загружает файл "i" "i = i + 1" - это переход к следующему файлу или каталогу или провал в подкаталог. Поэтому нужен возврат из функции в то место где она была вызвана, чтобы продолжить с того же места стека. Либо придется делать свой искусственный стек в отдельном массиве, что не хотелось бы. |
|||
32
kokamoonga
17.10.13
✎
06:45
|
(31) а не проще пробежаться по дереву, собрать все в очередь и потом спокойно загрузить все файлы из очереди?
|
|||
33
Помогите
17.10.13
✎
07:08
|
(32) хрен знает сколько памяти эта очередь будет занимать, и сколько доступно для скрипта. Когда делал как в (9) без setTimeout, то стека хватало на ~50 файлов.
Сейчас сделал со своим стеком, работает нормально. Но идея отличная, спасибо. Может переделаю, попробую таким способом тоже. |
|||
34
Помогите
17.10.13
✎
07:11
|
вот, рабочий код, проверял только в IE 11:
var files, folders, a; var arrFolders = []; function nextFile() { if (!files.atEnd()){ if( i = files.item() ) { a.oncanplay = function() { files.moveNext(); console.log (this.currentSrc + " !!!!"); setTimeout(function() { nextFile() }, 0) }; a.onerror = function() { files.moveNext(); console.log (this.currentSrc + " ----"); setTimeout(function() { nextFile() }, 0) }; a.setAttribute("src", i.Path); a.load(); } } else { if ( !folders.atEnd() ){ if ( f = folders.item() ) { arrFolders.push(folders); files = new Enumerator(f.files); folders = new Enumerator(f.SubFolders); console.log (f.Path + " #######"); setTimeout( function() { nextFile() }, 0 ); } else { folders.moveNext(); setTimeout( function() { nextFile() }, 0 ); } } else { if ( folders = arrFolders.pop() ) { folders.moveNext(); setTimeout( function() { nextFile() }, 0 ); } } } } var FSO = new ActiveXObject("Scripting.FileSystemObject"); a = new Audio(); var f = FSO.GetFolder("A:\\Флэшка в машину с музыкой"); a.preload = "none"; files = new Enumerator(f.files); folders = new Enumerator(f.SubFolders); nextFile(files, a, folders); |
|||
35
kokamoonga
17.10.13
✎
07:22
|
(33) если есть проблемы с доступной памятью (что мне довольно сложно представить в случае если в массив собрать пути к файлам), тогда почему не бы не использовать localStorage?
сохранять очередь кусками по 100/1000/10000/etc в localStorage и потом также кусками вычитывать. |
|||
36
Помогите
17.10.13
✎
07:26
|
(35) так точно не буду делать. Будем надеяться что хватит памяти. Или оставлю как есть.
|
|||
37
Помогите
17.10.13
✎
08:09
|
перенес и удалил лишнее:
function nextFile() { if (!files.atEnd()){ a.setAttribute("src", files.item().Path); a.load(); } else { if ( !folders.atEnd() ){ arrFolders.push(folders); files = new Enumerator(folders.item().files); folders = new Enumerator(folders.item().SubFolders); setTimeout( function() { nextFile() }, 0 ); } else { if ( folders = arrFolders.pop() ) { folders.moveNext(); setTimeout( function() { nextFile(); }, 0 ); } } } } |
|||
38
kokamoonga
17.10.13
✎
09:00
|
(37) эээ...
здесь второе "=" тоже оказалось лишним? if ( folders = arrFolders.pop() ) тут присваивание вместо сравнения же |
|||
39
Помогите
17.10.13
✎
10:04
|
(38) там переменной folders присваивается извлеченное значение из массива arrFolders. Это вроде как стек, самодельный.
|
|||
40
NS
17.10.13
✎
10:13
|
(31) именно так и делают, переписывают рекурсию на стеке.
обход дерева на стеке - это совсем просто. 1. добавляем в стек корень. 2. снимаем с стека значение. 3. добавляем в стек все дочерние. 4. к пункту 2. |
|||
41
Помогите
17.10.13
✎
13:14
|
(40) так и было сделано.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |