Answer the question
In order to leave comments, you need to log in
Why does magic happen in JS code?
Kind people, explain, maybe at the end of the working day and week I don’t notice any jamb in my code. I am writing a small application on a node, for convenience I write in CoffeeScript. The application needs to poll some servers via HTTP. Server data is stored as a list of JSON objects. I run through them in a loop and make a request for each and hang up a callback for the answer, in the callback I use the m variable to update the data for myself, regarding this particular monitor.
For requests I use the Request module. The code below, everything seems to be ok, I inserted the debug, as there were errors in the work. I output to the console for which monitors we are making a request, and accordingly I display in the callback when I received the answer to make sure that we took the data from all of them.
sync: (monitors) ->
for m in monitors
console.log "Sending sync request to monitor: #{JSON.stringify(m)}"
request.post({
url: "http://#{m.host}:#{m.port}",
form: {
request_id: 2
}
}, (err, response, body) =>
if err?
console.log "Monitor sync error: #{err.message}"
return 0
console.log "Response from monitor #{JSON.stringify(m)}"
data = JSON.parse(body)
urls = JSON.parse(@crypto_helper.decrypt(data.data))
@alert_urls(m, urls)
)
Sending sync request to monitor: {"monitor_id":1,"host":"z.zzz.zzz.zzz","port":YYYY,"name":"Local Monitor"}
Sending sync request to monitor: {" monitor_id":2,"host":"xxx.xxx.xxx.x","port":YYYY,"name":"Remote Monitor"}
Response from monitor {"monitor_id":2,"host":"xxx .xxx.xxx.xxx","port":YYYY,"name":"Remote Monitor"}
Response from monitor {"monitor_id":2,"host":"xxx.xxx.xxx.xxx","port" :YYYY,"name":"Remote Monitor"}
Answer the question
In order to leave comments, you need to log in
I'm not a CoffeeScript expert, but apparently your script generates the following JS code ( link to jsfiddle ):
var a = [ { id: 0 }, { id: 1 }, { id: 2 } ];
for(var i = 0; i != a.length; ++i)
{
var el = a[i];
setTimeout(function() {
console.log('timeout',el);
},100);
}
timeout Object { id: 2 }
timeout Object { id: 2 }
timeout Object { id: 2 }
In order for your code to run correctly, you can do this trick: pass el as an argument to a function that will return a callback function to us ( example on jsfiddle ):var a = [ { id: 0 }, { id: 1 }, { id: 2 } ]; var createCB = function(e){ return function() { console.log('timeout',e); }; }; for(var i = 0; i != a.length; ++i) { var el = a[i]; setTimeout(createCB(el),100); }
In this case, when creating a callback, we will always have the current value of el in the scope:timeout Object { id: 0 }
timeout Object { id: 1 }
timeout Object { id: 2 }
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question