Javascript (jQuery) все еще работает после того, как вся его работа завершена

Я использую jQuery для загрузки массивной таблицы в пакетах строк. Я загружаю начальные строки, затем я делаю вызовы $ .ajax, чтобы добавить строки в тело таблицы. По завершении вставки следующего фрагмента строк я вызываю метод для обработки следующего фрагмента строк. Смотрите код ниже. Проблема в том, что даже после того, как весь контент загружен, javascript по-прежнему утверждает, что выполняется - когда я перехожу на другую страницу, я жалуюсь, что есть подпрограмма javascript, замедляющая страницу, и я хочу прервать ее. На данный момент он не должен быть запущен! Эта подпрограмма первоначально вызывается из подпрограммы $ (function () {...}) (по готовности). Любые идеи, как я должен остановить это после того, как он завершил всю свою работу?

        function processNextChunk(c, t, s, p, x) {
        var args = "{company_ID:" + c + ",shareholdingType:" + t + ",startIndex:" + s + ",pageSize:" + p + ",stack:'" + x + "'}";
        //alert(args);
        $.ajax({
            type: "POST",
            url: "TestStructure6.aspx/GetNextHierarchyPage",
            data: args,
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function(msg) {
                //Append the content to the bottom of the table tag.
                //Returning 2 arguments from the result, hence the split (initial
                //value is an int, so not a big deal using pipe as a delimiter)
                if (msg.d.length > 0) {
                    var slash = msg.d.indexOf('|');
                    var r;
                    if (slash > 0) {
                        x = msg.d.substr(0, slash);
                        r = msg.d.substr(slash + 1, msg.d.length - slash);
                        $('#h  > tbody').append(r);
                        if (r.length > 0) {
                            var percent = (s + p) / totalRows * 100;
                            $('#counter').html(parseInt(percent) + '%');
                            setTimeout('processNextChunk(' + c + ', ' + t + ', ' + (s + p) + ', ' + p + ', "' + x + '")', 0);
                            //processNextChunk(c, t, s + p, p, x)
                        }
                        else {
                            $('#counter').html('');
                        }
                    }
                }
                return true;
            }
        });
        return true;
    }
13.10.2009 00:33:22
3 ОТВЕТА

Это может или не может решить вашу проблему, но вы не должны вызывать setTimeoutсо строковым аргументом.

Вместо этого вы должны дать ему функцию, например так:

setTimeout(function() {
    processNextChunk(c, t, s + p, p);
}, 0);

Кроме того, вместо того, чтобы писать $('#counter').html(''), вы можете написать $('#counter').empty().

Чтобы решить вашу проблему, уверены ли вы, что ваш setTimeoutвызов в рекурсии навсегда?

2
13.10.2009 00:39:28
спасибо за совет, теперь я добавил пустое утверждение. Даже когда я удалил таймер, я испытываю ту же проблему. Представление таймера было моей попыткой предотвратить рекурсию, которая, как я думал, может происходить, потому что processNextChunk вызывает сам себя.
user186906 13.10.2009 00:53:11
Добавление таймера не помогло бы - оно все еще вызывает себя. Используйте отладчик, чтобы пройтись по своему коду и проверить, восстанавливается ли он навсегда.
SLaks 13.10.2009 00:55:12
Отладчик показывает слово «пусто» рядом со значком блокнота под отладчиком VS2008 для каждого выполнения вызова $ .ajax. Он показывает по одному на каждый запрошенный кусок строк и прекращает их добавление, когда строк больше нет. Это подразумевает, что это не случай бесконечной рутины, а то, что я почему-то не так просто завершаю свою просьбу?
user186906 13.10.2009 01:00:25

Я не могу точно сказать, какие данные возвращаются в случае, если вы получили все строки. Я предполагаю, что он должен пройти проверку:

r = msg.d.substr(slash + 1, msg.d.length - slash);

Если это так, вы можете использовать clearTimeout () в вашем предложении else сразу после:

$('#counter').html('');
0
13.10.2009 00:46:57
вы правы, переменная "r" - это то, что содержит мой кусок строк. Отмена всех таймеров была бы проблемой, так как мне нужно было бы отслеживать все идентификаторы таймера, верно?
user186906 13.10.2009 00:55:23

Вы вызываете setTimeout (..., 0) или нулевой тайм-аут. Другими словами, вы не разрешаете браузеру обновлять / перерисовывать.

Обратите внимание, что это зависит от браузера - некоторые тесты на разных машинах в течение многих лет показывают, что для winxp требуется как минимум тайм-аут 50, в то время как для linux требуется тайм-аут 10. Похоже, это связано с минимальным временным интервалом в расписании ОС.

Если у вас быстрое соединение (например, разработка localhost), возможно, вызов ajax отвечает достаточно быстро, так что его установка на ноль является проблемой ...

Ваш код выглядит так, как будто он может просто увеличить время ожидания до чего-то большего, скажем, за 1 секунду, без вредных последствий.

[Вызов setTimeout со строковым аргументом совершенно допустим, но, похоже, вы не цитируете правильно. ]

0
13.10.2009 00:53:15
Браузеры перемещают значение тайм-аута до минимума, который они могут обработать. Тайм-аут будет выполнен, когда текущий поток будет завершен, и все браузеры обновятся между ними. Строковые значения для timeout эквивалентны eval () и, если не недействительны, просто плохая практика.
Borgar 13.10.2009 00:57:42
Я попробовал это, а также переключился на использование вызова функции вместо eval-версии, и это не имело никакого значения.
user186906 13.10.2009 02:15:57