0

I'm writing a browser extension for chrome that uses Web SQL for local storage. The code for both of these components seems to heavily rely on async operations. I have a good understanding of asynchronous operations but not a whole lot of experience writing code that relies this heavily on them.

For Example:

  var CSUID = "";
 //this is an async callback for handling browser tab updates
 function checkForValidUrl(tabId, changeInfo, tab) {
      getCookies("http://www.cleansnipe.com/", "CSUID", handleCookie);

      if(CSUID != ""){ //this could be in handleCookie if i could access the tab
         //do stuff with the tab
      } 
  }
  function handleCookie(cookie) {
     if (cookie != "" && cookie != null) {
        CSUID = cookie;
     }
  }

In order to overcome the lack of ability to pass/return variables into/from these handlers I find myself creating global variables and setting them in the handlers. Of course this doesn't work as expected because the variable is often accessed before the callback has executed.

What is the best practice for handling this situation? I thought to use global flags/counters with a while loop to pause execute but this seems messy prone to application hang.

NSjonas
  • 10,693
  • 9
  • 66
  • 92
  • Is jQuery an option? jQuery's deferreds system is beautiful and perfect for this sort of thing. – Mitya Jul 27 '12 at 16:44
  • @Utkanos: If you want to use Deferreds, dont use the ones from jQuery. – Bergi Jul 27 '12 at 16:49
  • @Bergi: Why not? I mean, I would not use jQuery *just* for the deferred objects, but what is the reason for not using them? – Felix Kling Jul 27 '12 at 16:56
  • @FelixKling: They don't implement the [CommonJS:Promises/A](http://wiki.commonjs.org/wiki/Promises/A) proposal, e.g. `then()` is broken. – Bergi Jul 27 '12 at 17:05
  • @Bergi - interesting - what's up with jQuery's `then()`? – Mitya Jul 27 '12 at 17:09
  • @Utkanos: in jQuery, `pipe` does what `then` should do: http://jaubourg.net/38261410 – Bergi Jul 27 '12 at 17:15

1 Answers1

1

If jQuery is an option, it has a beautiful system of what it calls deferred objects. It allows for graceful and effective management of asynchronous situations - or indeed synchronous, as the cases may be or vary.

(Deferreds aren't limited to just jQuery, but jQuery has a nice API for them).

Here's a simple example purely to demonstrate the concept.

//get data func
function get_data(immediate) {
    //if immediate, return something synchonously
    if (immediate)
        return 'some static data';
    //else get the data from something over AJAX
    else
        return $.get('some_url');
}

//two requests two get data - one asynchronous, one synchronous
var data1 = get_data(true), data2 = get_data();

//do something when both resolved
$.when(data1, data2).done(function(data1, data2) {
    //callback code here...
});

Deferreds don't have to involve AJAX; you can create your own deferred objects (jQuery's AJAX requests automatically make and return them) and resolve/reject them manually. I did a blog post on this a few months back - it might help.

Mitya
  • 33,629
  • 9
  • 60
  • 107
  • There are also various alternatives which implement the jQuery deferred interface, without having to load jQuery. For example: https://github.com/warpdesign/Standalone-Deferred – Felix Kling Jul 27 '12 at 17:05
  • Perfectly true - jQuery didn't invet the deferreds concept, but it's a nice API for it and it's the one I know, hence my answer :) – Mitya Jul 27 '12 at 17:08
  • hmm... not quite grasping their use. I'll accept if you show code that would handle something more similar to what I have posted above. Not really trying to be lazy, I just think this question would be better with a more relevant code example. – NSjonas Jul 27 '12 at 20:45
  • Also how to Deferreds handle nested async calls? does it wait for all calls to return or just the top level function? – NSjonas Jul 27 '12 at 21:12
  • I would suggest looking into these, if they whet your interest. They are very flexible. How you resolve them (resolution is automatic in the case of AJAX, manual in other cases, via methods like `resolve()`) is up to you. – Mitya Jul 27 '12 at 22:10