【问题标题】:Change the in array functions context and pass the array to $.when更改 in 数组函数上下文并将数组传递给 $.when
【发布时间】:2015-04-29 00:15:14
【问题描述】:

大家好,我有这种工作方法可以定期调用一组函数。

在这里您可以看到具有在数组中添加/删除函数的方法以及启动/停止调用间隔的函数的对象。 (你必须只关注 start 方法,但我把它们都放在了澄清)

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 = [];
    }
}

我想使用setTimeout 而不是setInterval 转换start 方法,我写了这样的内容:

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

    setTimeout(doLoop, _updateFrequence);
}

如何更改数组函数 _functionsToCall 的上下文,就像我在之前的方法中所做的那样,将 iframe 上下文传递给每个函数?

【问题讨论】:

  • 似乎你想要的只是循环arguments of $.when.done
  • 我必须遍历每个函数来改变上下文......那么我如何在 $.when 语句中做到这一点?
  • 我想更好地解释一下我的应用程序的环境。我有一个包含我在上面提出的 js 函数的包含页面,在这个页面内我将加载/卸载一些 iframe。在每个 iframe 中,我可以向“_callRecurringFunctions”数组添加/删除一个 iframe 函数,所以这个数组中的所有函数可以以一定的频率执行。主要问题是将每个函数的执行上下文设置为将其添加到数组中的正确 iframe
  • 那么你为什么不能使用arguments.length 并运行已经存在的类似循环呢?
  • mhh ..也许你在谈论一些我不知道的东西..你能提供一个例子吗?我现在正在寻找 $.proxy,我认​​为它应该是一个可能的解决方案

标签: javascript jquery arrays settimeout .when


【解决方案1】:

我已经用另一种方式解决了我的问题... 现在我有一个函数数组,每个函数都返回一个承诺; 这些函数可以在不同的 iframe 中声明; 当每个承诺都解决时,我会增加一个计数器,当所有承诺都解决时,我可以重新开始另一个循环。 显然,在每次迭代中,数组可以包含不同数量的函数。

我想知道是否有更好的方法来完成这项任务,或者我的代码是否存在一些问题。 谢谢大家。

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)
    }

【讨论】:

    猜你喜欢
    • 2011-08-03
    • 1970-01-01
    • 2015-08-16
    • 1970-01-01
    • 2011-11-24
    • 2020-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多