【问题标题】:define ajax callback overrides in loop在循环中定义 ajax 回调覆盖
【发布时间】:2014-04-07 06:11:09
【问题描述】:

我已经制作了一个 ajax 预过滤器来等待模态窗口在执行原始回调之前消失,并且效果很好......

$.ajaxPrefilter ( options, originalOptions, jqXHR )->

    # perhaps these could be defined in a loop from an array
    jqXHROriginaldone = jqXHR.done
    jqXHROriginalfail = jqXHR.fail

    jqXHR.done = ->
        args = arguments
        myfunc = ->
            $(listener).off "ajax.progress.dismissed", myfunc
            jqXHROriginaldone args
        $(listener).on "ajax.progress.dismissed", myfunc

    jqXHR.fail = ->
        args = arguments
        myfunc = ->
            $(listener).off "ajax.progress.dismissed", myfunc
            jqXHROriginalfail args
        $(listener).on "ajax.progress.dismissed", myfunc

我不喜欢为每种状态类型重复我的代码...我想更改以便可以在循环中设置所有状态(完成/失败/等...)...

$.ajaxPrefilter ( options, originalOptions, jqXHR )->

    # object to store original callbacks for later use
    originals = {}

    for status in ['done','fail']

        originals[status] = jqXHR[status]
        jqXHR[status] = ->
            args = arguments
            myfunc = ->
                $(listener).off "ajax.progress.dismissed", myfunc
                originals[status] args
            $(listener).on "ajax.progress.dismissed", myfunc

对我来说它看起来像等效代码,但它失败了,并且在控制台中没有显示错误,只是没有运行回调函数。

为什么我的循环方法有效?

【问题讨论】:

  • 我花了几分钟试图弄清楚这一点......找不到任何明显的东西。你有没有扔很多console.log's 来看看发生了什么/什么时候发生的事情?
  • @BradM 感谢您抽出宝贵的时间。我没有将控制台日志放在那里,但我确实在调试器中逐行检查,我可以检查的一切似乎都很好。这些函数似乎是按预期定义的,它正在调用它们,只是它似乎从未调用回调函数。显然我遗漏了一些东西 - 我怀疑 javascript 本身已经坏了。

标签: javascript jquery ajax coffeescript


【解决方案1】:

在循环内构建函数会引发危险信号。您的 status 变量在实际使用之前不会被评估。如果我们看看你的myfunc

myfunc = ->
    $(listener).off "ajax.progress.dismissed", myfunc
    originals[status] args

我们将看到一个 status 引用,在调用 myfunc 之前不会对其进行评估。发生这种情况时,status 将始终为 'fail',因为这就是循环结束时的 status

JavaScript 中通常的解决方案是对循环体使用 SIF:

for(i = 0; i < n; ++i)
    (function(i) {
        //...
    })(i);

但在 CoffeeScript 中有 do:

当使用 JavaScript 循环生成函数时,通常会插入一个闭包包装器以确保循环变量被封闭,并且所有生成的函数不只是共享最终值。 CoffeeScript 提供了 do 关键字,它立即调用传递的函数,转发任何参数。

所以这样的事情应该会更好:

for status in ['done','fail']
    do (status) ->
        # What you have now...

【讨论】:

    猜你喜欢
    • 2014-09-02
    • 1970-01-01
    • 2019-11-16
    • 2013-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-17
    • 2020-05-05
    相关资源
    最近更新 更多