Async.md

**Callback functions in loops in Javascript** A pseudo code would look thus: <br> ``` for (var n=0; n < thingstotweet.length; n++) {       // tweet function       Tweet(thingstotweet[n], function(e,r) {          // the call back function           //if no error, then save the id of the tweet           if (!e) {               Db.save(thingstotweet[n]);           }       })    } ``` In Javascript, this is a faulty implementation. If you implement such a solution for having callbacks inside a loop you would soon find out that the things gets out of sync. For instance in the tweeting example, one tweet would be sent while a different one would be saved in its place. And the reason is simple: It takes time before the function sending the tweet returns and the call back is called. And since functions call like this in Javascript are non blocking, in the time it takes before the calling function returns and the callback called, the value of n would have changed leading to saving the wrong item. For example. 1. Start the loop when n is 0; 2. Tweet the item in index 0 in the thingstobetweet list 3. The tweet function is sending the tweet but it takes a couple of seconds. 4. Value of n increased to 1. Still tweet has not been sent, so call back Is not to be called yet 5. Value of n increased to 2. Still tweet has not been sent, so call back is not to be called yet 6. Value of n increased to 3. Finally the tweet was sent successfully, time to call the callback 7. The call back is called. But n is now 3. So thingstobetweet[3] is saved for a tweet at thingstobetweet[0] How then do you deal with this? What would be the correct way to implement a task that needs a callback function inside a loop? There are two ways I normally implement a solution for this specific scenario: **Use Closures** In a previous post I briefly explained closures in Javascript.  Dealing with callbacks in loop is a situation where closures can be put to use. The solution is to create a closure for the tweet function. A pseudo implementation would be thus: ``` for (var n=0; n < thingstotweet.length; n++) {       (function(clsn){           // tweet function           Tweet(thingstotweet[clsn], function(e,r) {               // call back function              //if no error, then save the id of the tweet               if (!e) {                   Db.save(thingstotweet[clsn]);               }           });       })(n)  } ``` You can check the [post on closures in Javascript](http://geekabyte.blogspot.nl/2013/04/closures-are-hard-not-really-simple.html) for more information and why the pseudo code above works. **Use Recursive Function** The other solution is to implement a recursive function.  An implementation would be thus: ``` var tweetRecursive = function (n) {       if (n < thingstotweet.length) {           // tweet function            Tweet(thingstotweet[clsn], function(e,r) {               // the call back function               //if no error, then save the id of the tweet               if (!e) {                  Db.save(thingstotweet[clsn]);                  tweetRecursive(n + 1);                }            });        }   }   //start the recursive function   tweetRecursive(0); ``` The logic to send the tweet is defined as a recursive function.  This works because the function to tweet the next item (the recursive function) is also called in the callback function. This would ensure that there is no out of sync situation and the correct tweet would be saved for the one that was sent. The only repercussion in this implementation is that it breaks the asynchronous nature as the tweets would be sent in a procedural manner, i.e. one after the other instead of asynchronous fashion.
[Callback functions] Callback functions in loops in Javascript #JavaScript #Async

Be the first to comment

You can use [html][/html], [css][/css], [php][/php] and more to embed the code. Urls are automatically hyperlinked. Line breaks and paragraphs are automatically generated.