Ajax请求的奇怪行为

时间:2013-06-26 23:31:45

标签: javascript jquery ajax coffeescript

我有一个循环,正在制作多个ajax获取。

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

dataType中的console.log始终返回@dataTypes中的最后一个dataType,尽管第一个函数中的console.log dataType同时显示两者,表明正在发生循环。

我也打印了网址 - 它们都不同,但我得到的响应与上一个dataType附加到someUrl完全相同,并且使用该网址进行了多次获取。

为什么会这样?我认为这与回调的性质有关。

1 个答案:

答案 0 :(得分:0)

您的问题是success回调:

success : (data) => @populateSearchIndices(data, dataType)

只是抓取dataType作为引用,在触发回调之前不会对其进行评估。到那时,dataType将成为@dataTypes数组中的最后一个值,并且所有回调都将使用相同的值。

您需要强制dataType在循环体中进行评估,并且CoffeeScript具有do

  

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

所以你想要更像这样的东西:

for dataType in @dataTypes
  do (dataType) ->
    url = someUrl + dataType
    #... as before

如果您查看相应的JavaScript,您将看到您的循环体转换为使用dataType作为参数调用的函数,函数包装器和执行强制dataType为每个循环迭代进行评估(而不是仅仅引用)。

您的url行为符合预期,因为您在构建时评估了dataType

url = someUrl + dataType

然后在$.ajax调用中使用它,而不是拖动引用。