对于延迟的.done()来说,使用外部作用域中的变量是安全的

时间:2015-02-18 19:46:43

标签: jquery ajax jquery-deferred deferred

在以下代码中,完成功能是否始终可以使用myVar?如果我的deferreds需要很长时间才能完成工作并且代码已经移动,那么它是否会知道myVar

function doWork() {
    var deferreds = [deferredObject1, deferredObject2];

    var myVar = "Derp";    

    jQuery.when.apply(null, deferreds).done(() => {
       doStuffToMyVar(myVar);
    });
}

1 个答案:

答案 0 :(得分:1)

在更高的范围内使用变量总是可以的,.done()处理程序在这方面没有区别。因此,在myVar处理程序中使用.done()非常好。

您需要注意的是变量何时发生变化的时间。正如我猜想的那样,.done()处理程序将在未来的某个时间被调用,并且它的确切时间可能是未知的(假设正在使用异步操作)。因此,如果有任何其他代码可以修改myVar,则必须确保您知道该修改如何与.done()处理程序的时间相互作用。

在一个极端的例子来说明这一点,这会给你带来问题:

function doWork() {
    var deferreds = [deferredObject1, deferredObject2];

    var myVar = "Derp";    

    jQuery.when.apply(null, deferreds).done(() => {
       doStuffToMyVar(myVar);
    });
    myVar = null;
}

因为myVar会在调用null处理程序之前设置为.done(),因此您最终会得到doStuffToMyVar(null),这不是您想要的。< / p>

显然有更多微妙的例子,其中函数的其他部分或在.done()处理程序实际被调用之前运行的其他方法可能会从您下面更改数据。这并不意味着有任何规则不使用更高范围的变量,只是你应该知道这些类型的问题,如果它可能是你的代码中的问题,那么你可以通过制作一个来防止它有问题的变量的副本,创建一个新的闭包来传递变量等等......