延迟的 .done() 使用外部范围的变量是安全的
Is is safe for deferred .done() to use a variable from outer scope
在下面的代码中,myVar
是否总是对 done 函数可用?如果我的 deferreds
需要很长时间才能完成工作并且代码已经移动,它会知道 myVar
吗?
function doWork() {
var deferreds = [deferredObject1, deferredObject2];
var myVar = "Derp";
jQuery.when.apply(null, deferreds).done(() => {
doStuffToMyVar(myVar);
});
}
在更高范围内使用变量总是可以的,.done()
处理程序在这方面没有什么不同。因此,在 .done()
处理程序中使用 myVar
是完全没问题的。
你需要注意的是变量变化的时机。正如我假设您知道的那样,.done()
处理程序将在未来的某个时间被调用,并且它的确切时间可能是未知的(假设正在使用异步操作)。因此,如果有任何其他代码可以修改 myVar
,您必须非常确保知道该修改可能如何与 .done()
处理程序的时间交互。
用一个极端的例子来说明这一点,这会给你带来麻烦:
function doWork() {
var deferreds = [deferredObject1, deferredObject2];
var myVar = "Derp";
jQuery.when.apply(null, deferreds).done(() => {
doStuffToMyVar(myVar);
});
myVar = null;
}
因为 myVar
在调用 .done()
处理程序之前将设置为 null
,因此您最终会得到 doStuffToMyVar(null)
,这不是您想要的.
显然还有更微妙的示例,其中在实际调用 .done()
处理程序之前 运行 函数的其他部分或其他方法可能会从您的下方更改数据。这并不意味着有任何规则不能使用来自更高范围的变量,只是你应该意识到这些类型的问题,如果它可能是你的代码中的问题,那么你可以通过制作一个有问题的变量的副本,创建一个新的闭包来传递变量,等等...
在下面的代码中,myVar
是否总是对 done 函数可用?如果我的 deferreds
需要很长时间才能完成工作并且代码已经移动,它会知道 myVar
吗?
function doWork() {
var deferreds = [deferredObject1, deferredObject2];
var myVar = "Derp";
jQuery.when.apply(null, deferreds).done(() => {
doStuffToMyVar(myVar);
});
}
在更高范围内使用变量总是可以的,.done()
处理程序在这方面没有什么不同。因此,在 .done()
处理程序中使用 myVar
是完全没问题的。
你需要注意的是变量变化的时机。正如我假设您知道的那样,.done()
处理程序将在未来的某个时间被调用,并且它的确切时间可能是未知的(假设正在使用异步操作)。因此,如果有任何其他代码可以修改 myVar
,您必须非常确保知道该修改可能如何与 .done()
处理程序的时间交互。
用一个极端的例子来说明这一点,这会给你带来麻烦:
function doWork() {
var deferreds = [deferredObject1, deferredObject2];
var myVar = "Derp";
jQuery.when.apply(null, deferreds).done(() => {
doStuffToMyVar(myVar);
});
myVar = null;
}
因为 myVar
在调用 .done()
处理程序之前将设置为 null
,因此您最终会得到 doStuffToMyVar(null)
,这不是您想要的.
显然还有更微妙的示例,其中在实际调用 .done()
处理程序之前 运行 函数的其他部分或其他方法可能会从您的下方更改数据。这并不意味着有任何规则不能使用来自更高范围的变量,只是你应该意识到这些类型的问题,如果它可能是你的代码中的问题,那么你可以通过制作一个有问题的变量的副本,创建一个新的闭包来传递变量,等等...