LostKobrakai Posted February 11, 2015 Share Posted February 11, 2015 Can somebody help me out with some Javascript, which I can't get my head around. I know the theory about closure and callbacks, but how the heck can I have something that reports back after multiple callbacks are all finished. Now I know again why I dislike node so much. I'm trying to build a local html-only page, that uses openstreetmaps so to add latitude and longitude to a csv table based on the city. Getting it to call the rest api of osm is easy, but I can't figure out, how to spit out the new csv after all those calls are done. function getGeoCodes(jsonFromCsv){ for (var i = json.length - 1; i >= 0; i--) { //AJAX requests and adding the lat / lon to the json object } // After everything is done reformatToCsv(json); } Edit: Also I'd like this calls to be parallel and not one after another. Link to comment Share on other sites More sharing options...
Jan Romero Posted February 11, 2015 Share Posted February 11, 2015 Feel like you left out the most interesting parts there It sounds like you’re not using jQuery, but if you did, Ajax requests would return Deferred objects that expose done events. You could then use $.when to bind these Deferreds together into a single Deferred that fires such an event once for the entire queue, once all “inner” Deferreds have finished. I recently had to wrap my head around this. Voodoo is an apt description. I think in vanilla JS (I hope this is not the name of some JS library ) you would create an XMLHttpRequest object for each request, whose onreadystatechange events you handle in one function. There you could naively count the successes in a global variable and do your thing once you have all of them. So it kinda depends on what the requests look like and what events you can subscribe to. The requests should run in parallel if you simply send() them one after the other, i. e. the program will not wait for the server response until it executes the next request. 1 Link to comment Share on other sites More sharing options...
Mike Rockett Posted February 11, 2015 Share Posted February 11, 2015 ... (I hope this is not the name of some JS library ) ... Love this: http://vanilla-js.com/ 2 Link to comment Share on other sites More sharing options...
diogo Posted February 11, 2015 Share Posted February 11, 2015 Taking what you have: function getGeoCodes(jsonFromCsv, callback){ // <- I added the callback parameter WITHOUT parentheses for (var i = json.length - 1; i >= 0; i--) { //AJAX requests and adding the lat / lon to the json object } // After everything is done callback(json); // <- and call it inside the function, just as you had it } // when calling getGeoCodes, you will have to pass the function as a parameter getGeoCodes(yourJson, reformatToCsv) // <- here is where we pass the function, also WITHOUT parentheses PS: I'm not sure what is jsonFromCsv in your case, but here I'm assuming it's some other parameter that you will need and it's not related to the callback function. PS2: I renamed the function inside the other function to "callback" to make it clear that you don't need to use the name of the function there, only while calling it outside. PS3: The reason that I insist so much on having the function without parentheses on the parameters is because the parentheses will cause the function to be called immediately. We want to pass it only as a reference, so we can call it only later inside the function. PS4: by the way @Jan, I didn't comment on your avatar before, but next time make sure you add a custom avatar before it's too late 3 Link to comment Share on other sites More sharing options...
Jan Romero Posted February 11, 2015 Share Posted February 11, 2015 That’s how callbacks work, but I believe LostKobrakai can’t use a standard callback, because his requests will be asynchronous. So the callback would get executed as soon as all requests have been made, but it won’t wait for the actual responses. For that he’ll have to use events. So either pool the events of the request objects and fire your own event when all are done, or have a single function handling all requests and executing the callback upon completion. @diogo hehe, I’m glad you got that reference %) @Mike Anthony that’s brilliant! I’ll have to save that link Link to comment Share on other sites More sharing options...
LostKobrakai Posted February 11, 2015 Author Share Posted February 11, 2015 There you could naively count the successes in a global variable and do your thing once you have all of them. That was exactly the right hint. Feel like you left out the most interesting parts there I don't think so. In my eyes these big callback wars are a wast of time and asyncron code would deserve a easier way to manage stuff. Instead of pasing data though a shitload of callbacks, it would be so nice to be able to just return stuff after it's done. In a way, that the callback just "resumes" where it left. Link to comment Share on other sites More sharing options...
diogo Posted February 11, 2015 Share Posted February 11, 2015 Ya, sorry, I should have read the question better Based on Jan's idea, I think a good approach would be to, for each request callback, add 1 to that global variable on success, and check if the variable is already the total of the requests. If so, fire the function right there. Link to comment Share on other sites More sharing options...
LostKobrakai Posted February 11, 2015 Author Share Posted February 11, 2015 I've it working already, but yeah did exactly that. 1 Link to comment Share on other sites More sharing options...
Soma Posted February 11, 2015 Share Posted February 11, 2015 https://www.promisejs.org 1 Link to comment Share on other sites More sharing options...
qtguru Posted February 11, 2015 Share Posted February 11, 2015 Promises are way better, although I don't like the Promises in jQuery they seem off compared to Dojotoolkit and Q Link to comment Share on other sites More sharing options...
Recommended Posts