I'm writing a Chrome extension for my own use. I'm querying the current tab's index from an injected script like this:
[injected script]
chrome.runtime.sendMessage({whatIsMyIndex:1}, function(response){
   var myIndex = response.index;
});
[background script]
chrome.runtime.onMessage.addListener(
   function(request, sender, sendResponse) {
      if (request.whatIsMyIndex){
         sendResponse({index: sender.tab.index});
      }
   }
);
Now this is all good and fine, but then I need to return the url of the first tab as well:
[injected script 2]
chrome.runtime.sendMessage({whatIsMyIndex:1}, function(response){
   var myIndex = response.index;
   var url = response.url;
});
[background script 2]
var url;
//this uses sendResponse when the requested values arrive
function respond(sendResponse, index){
   if(typeof(url)!="undefined"){
      sendResponse({index:index, url:url});
   } else {
      setTimeout(respond, 15, sendResponse, index);
   }
}
chrome.runtime.onMessage.addListener(
   function(request, sender, sendResponse) {
      if (request.whatIsMyIndex){
         chrome.tabs.query({index:0, currentWindow:true}, function(tabs){
            url=tabs[0].url;
         }
         setTimeout(respond, 15, sendResponse, sender.tab.index);
         return true; //so i can use sendResponse later
      }
   }
);
Now, this code works just fine. My question is, is there any way to accomplish this without the need for setTimeout? Adding a fixed 15ms delay doesn't seem right.
If only I could get chrome.tabs.query's callback to take my sendResponse() as a parameter...
(Storing sendResponse() in a global variable is not possible, since there will be ~20 tabs doing this at the same time, and all of them need their own responses.)
I don't need any working (or not working) code here, only some ideas/guidelines.
 
     
    