问题
I have a loop that is making multiple ajax gets.
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
The console.log in dataType always returns the last dataType in @dataTypes, despite the fact that the console.log dataType in the first function displays both, suggesting that a loop is occurring.
I printed out the url as well - they're both different, but the response I get is the exact same as if the last dataType were appended to someUrl and multiple gets were made with that url.
Why is this happening? I think this has something to do with the nature of callbacks.
回答1:
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.
来源:https://stackoverflow.com/questions/17332141/weird-behaviour-with-ajax-request