Показать сообщение отдельно
  #1 (permalink)  
Старый 03.09.2021, 10:27
Интересующийся
Отправить личное сообщение для Azazaza Посмотреть профиль Найти все сообщения от Azazaza
 
Регистрация: 08.11.2011
Сообщений: 19

Переполнение памяти при работе с дерними окнами
Здравствуйте. У меня задача - пройти по ссылкам на странице, и каждую ссылку открыть в новом дочернем окне, провести в нем определенные действия, вернуть результат выполнения в родительское окно и закрыть дочернее.

Я написал функцию, которая вызывается в цикле. В нее передаются URL из ссылки и дейтсвие, которое необходимо выполнить в дочернем окне. Она открывает новое дочернее окно, и возвращает Promise - ждет пока дочернее окно выполнит свою задачу.

/**
 * Функция выполняет определенное действие на дочерней странице.
 * Ожидается объект с результатом выполнения
 * 
 * @param url URL дочерней страницы
 * @param action Действие. которое требуется произвести
 * @param timeout Максимальное время ожидание результата
 * @returns {Promise}
 */
window.promiseDoActionChildWindow = function (url, action, timeout)
{
    return new Promise(async (resolve, reject) =>
    {
        // Формирование URL
        url = new URL(url);
        url.searchParams.set('helper_action', action);
        // Открытие нового дочернего окна
        window.childWindow = window.open(url);

        // Функция, которая вызывается из дочернего окна после выполнения работ на ней
        window.closeChildWindow = function (result)
        {
            clearTimeout(window.actionTimeout);
            window.childWindow.close();
            if (result.status === 'ok')
            {
                resolve(result);
            }
            else
            {
                reject(result);
            }
        }

        // Принудительное закрытие дочернего окна по таймеру
        window.actionTimeout = setTimeout(function ()
        {
            window.childWindow.close();
            reject({
                status: 'error',
                message: 'Окно закрыто по таймеру.',
                url: url,
                action: action
            });
        }, timeout || 10000);

    });
}


После выполнения действия в дочернем окне - из него вызывается инициализированная в функции promiseDoActionChildWindow() функция closeChildWindow().

window.opener.closeChildWindow(result);


Такой способ реализации работает, но на каждой итерации сжирает плюс примерно 30Мб оперативной памяти, а итераций очень много. Я пробовал делать интервал в 10 секунд между итерациями, что бы браузер успевал почистить память, но результат тот-же.

Еще безуспешно пробовал обнулять ссылки так:

window.promiseDoActionChildWindow= function (url, action, timeout)
{
    return new Promise(async (resolve, reject) =>
    {
        url = new URL(url);
        url.searchParams.set('helper_action', action);
        window.childWindow = window.open(url);

        window.closeChildWindow = function (result)
        {
            window.closeChildWindow = undefined;
            clearTimeout(window.actionTimeout);
            window.actionTimeout = null;
            window.childWindow.close();
            window.childWindow = null;
            if (result.status === 'ok')
            {
                resolve(result);
            }
            else
            {
                reject(result);
            }
        }

        window.actionTimeout = setTimeout(function ()
        {
            window.closeChildWindow = undefined;
            window.childWindow.close();
            window.childWindow = null;
            reject({
                status: 'error',
                message: 'Окно закрыто по таймеру.',
                url: url,
                action: action
            });
        }, timeout || 10000);

    });
}


Помогите разобраться, в чем проблема.

Последний раз редактировалось Azazaza, 03.09.2021 в 10:33.
Ответить с цитированием