Измените контекст функций массива и передайте массив в $.when

Привет всем, у меня есть этот рабочий метод для вызова массива функций через повторяющиеся интервалы.

Здесь вы можете увидеть объект с методами добавления / удаления функций в массиве и функциями для запуска / остановки интервала вызова. (Вы должны сосредоточиться только на метод начала, но я поставил их все для пояснения)

function updateEngine() {
    var _callRecurringFunctions = null,
        _functionsToCall = [],
        _functionIds = [],
        _functionApps = [];

    updateEngine.prototype.addFunction = function (appCode, funcId, func) {
        if ($.isFunction(func) &&
            $.inArray('_' + appCode + '_' + funcId, _functionIds) == -1) {
            _functionApps.push(appCode);
            _functionIds.push('_' + appCode + '_' + funcId);
            _functionsToCall.push(func);
        }
    }

    updateEngine.prototype.removeFunction = function (appCode, funcId) {
        if (funcId == null) {   // remove all functions relative to an app
            for (var x = 0; x < _functionApps.length; x++) {
                if (_functionApps[x] == appCode) {
                    _functionApps.splice(x, 1);
                    _functionIds.splice(x, 1);
                    _functionsToCall.splice(x, 1);
                }
            }
        }
        else {      // remove the single app function
            var pos = $.inArray('_' + appCode + '_' + funcId, _functionIds);

            if (pos >= 0) {
                _functionApps.splice(pos, 1);
                _functionIds.splice(pos, 1);
                _functionsToCall.splice(pos, 1);
            }
        }
    }

    updateEngine.prototype.start = function () {
        _callRecurringFunctions = setInterval(function () {

            for (var x = 0; x < _functionsToCall.length; x++) {

                var frame = null;

                // id == -1:    local function
                // id == 0:     function defined in home iframe
                // id > 0:      function defined in an app iframe
                if (_functionApps[x] >= 0)
                    frame = _portalContent.find("iframe[id='" + _functionApps[x] + "']");

                if (frame != null && frame.get(0) != null) {
                    var iframeContent = frame.get(0).contentWindow || frame.get(0).contentDocument;
                    _functionsToCall[x].apply(iframeContent);
                }
                else
                    _functionsToCall[x]();
            }

        }, _updateFrequence); // tick every 5 seconds
    }

    updateEngine.prototype.stop = function () {
        clearInterval(_callRecurringFunctions);
        _callRecurringFunctions = null;
        _functionApps = [];
        _functionIds = [];
        _functionsToCall = [];
    }
}

Я хочу преобразовать start метод с использованием setTimeout вместо setInterval и я написал что-то вроде этого:

updateEngine.prototype.start = function () {
    function doLoop() {
        $.when.apply($, _functionsToCall)
            .done(function() {
                setTimeout(doLoop, _updateFrequence);
            });
    }

    setTimeout(doLoop, _updateFrequence);
}

Как я могу изменить контекст функций массива _functionsToCall как я делал в предыдущем методе, чтобы передать контекст iframe для каждой функции?

1 ответ

Я решил свою проблему по-другому... Теперь у меня есть массив функций, которые возвращают обещание каждая; Эти функции могут быть объявлены внутри различных iframes; Я увеличиваю счетчик, когда каждое обещание разрешено, и когда все обещания разрешены, я могу начать снова с другого цикла. Очевидно, что на каждой итерации массив может содержать разное количество функций.

Я хотел бы знать, есть ли лучший способ выполнить эту задачу или есть какие-то проблемы с моим кодом. Спасибо вам всем.

updateEngine.prototype.start = function () {
        function doLoop() {
            var count = 0,
                functionsCount = _functionsToCall.length

            for (var x = 0; x < functionsCount; x++) {

                var frame = null;

                // id == -1:    local function
                // id >= 0:     function defined in iframe
                if (_functionApps[x] >= 0)
                    frame = _portalContent.find("iframe[id='" + _functionApps[0] + "']");

                if (frame != null && frame.get(0) != null) {
                    var iframeContent = frame.get(0).contentWindow || frame.get(0).contentDocument;
                    $.when.apply(iframeContent, _functionsToCall[x]())
                        .done(function () {
                            count++;
                        })
                        .fail(function () {
                            count++;
                            console.log("err")
                        })
                        .always(function () {
                            if (count == functionsCount)
                                setTimeout(doLoop, _updateFrequence)
                        })
                }
                else
                    $.when(_functionsToCall[x]())
                        .done(function () {
                            count++;
                        })
                        .fail(function () {
                            count++;
                            console.log("err")
                        })
                        .always(function () {
                            if (count == functionsCount)
                                setTimeout(doLoop, _updateFrequence)
                        })
            }
        }

        setTimeout(doLoop, _updateFrequence)
    }
Другие вопросы по тегам