Javascript Ajax请求的奇怪行为
我有一个循环,可以生成多个ajax getJavascript Ajax请求的奇怪行为,javascript,jquery,ajax,coffeescript,Javascript,Jquery,Ajax,Coffeescript,我有一个循环,可以生成多个ajax get for dataType in @dataTypes url = someUrl + dataType console.log(dataType) console.log url $.ajax( url : url type : 'GET' success : (
for dataType in @dataTypes
url = someUrl + dataType
console.log(dataType)
console.log url
$.ajax(
url : url
type : 'GET'
success : (data) => @populateSearchIndices(data,dataType)
)
populateSearchIndices:(data,dataType)->
console.log "looking at what indexes are there"
console.log dataType
indices = []
for object in data
indices = indices.concat(Object.keys(object))
console.log "indices"
console.log indices
arr = @typeIndexMap[dataType]
if arr
@typeIndexMap[dataType] = @typeIndexMap[dataType].concat(indices)
else
@typeIndexMap[dataType] = indices
console.log "typeIndexMap"
console.log @typeIndexMap
数据类型中的console.log始终返回@dataTypes中的最后一个数据类型,尽管第一个函数中的console.log数据类型同时显示这两个数据类型,这表明循环正在发生
我也打印出了url——它们都不同,但我得到的响应完全相同,就像最后一个数据类型被附加到某个url,并且使用该url进行了多次获取一样
为什么会这样?我认为这与回调的性质有关。您的问题是您的
成功
回调:
success : (data) => @populateSearchIndices(data, dataType)
只是将数据类型
作为引用,在触发回调之前不会对其求值。到那时,dataType
将是@dataTypes
数组中的最后一个值,并且所有回调都将使用相同的值
您需要强制在循环体中计算dataType
,CoffeeScript为此提供了:
当使用JavaScript循环生成函数时,通常会插入一个闭包包装器,以确保循环变量被关闭,并且所有生成的函数不只是共享最终值。CoffeeScript提供do
关键字,该关键字立即调用传递的函数,转发任何参数
所以你想要更像这样的东西:
for dataType in @dataTypes
do (dataType) ->
url = someUrl + dataType
#... as before
如果查看相应的JavaScript,您将看到循环体被转换为一个函数,该函数以dataType
作为参数调用,函数包装器和执行强制dataType
为每个循环迭代求值(而不仅仅是引用)
您的url
的行为符合预期,因为您在构建数据类型时对其进行了评估:
url = someUrl + dataType
然后在$.ajax
调用中使用它,而不是四处拖动引用