0

我有一个循环,正在制作多个 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 显示了两者,这表明正在发生循环。

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

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

4

1 回答 1

0

Your problem is that your success callback:

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

is just grabbing dataType as a reference that won't be evaluated until the callback is triggered. By the time that happens, dataType will be the last value in the @dataTypes array and all of your callbacks will use that same value.

You need to force dataType to be evaluated in the loop body and CoffeeScript has do for that:

When using a JavaScript loop to generate functions, it's common to insert a closure wrapper in order to ensure that loop variables are closed over, and all the generated functions don't just share the final values. CoffeeScript provides the do keyword, which immediately invokes a passed function, forwarding any arguments.

So you want something more like this:

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

If you have a look at the corresponding JavaScript, you'll see that your loop body is converted to a function that is called with dataType as a parameter, the function wrapper and execution forces dataType to be evaluated (rather than just referenced) for each loop iteration.

Your url behaves as expected because you evaluated dataType when you build it:

url = someUrl + dataType

and then use it in the $.ajax call rather than dragging a reference around.

于 2013-06-27T00:03:50.230 回答