0

How do I store a current tab's URL in a variable so it can be accessed later on? I've done some googling but don't quite understand asynchronous callback functions.

var currentTab;
chrome.tabs.getSelected(null, function(tab) { currentTab = tab.url; });
console.log(currentTab);

user2409821
  • 13
  • 1
  • 3
  • [After calling chrome.tabs.query, the results are not available](http://stackoverflow.com/a/11689804/938089) explains the concept of asynchronous code in the context of a Chrome extension, read it and try to understand the analogy. – Rob W May 26 '13 at 09:42
  • Ah okay I _kind of_ understand what is going on now. So I have no way of accessing a variable that is set _inside_ an async function, even if it's declared on top (globally)? – user2409821 May 27 '13 at 01:11
  • Certainly not in the way you've written in the question. You have to somehow delay the access to the variable, so the proposed solution in the other answer is the best option (another method would be the use of timers, eg `setTimeout`, but that leads to unpredictable results). – Rob W May 27 '13 at 07:58

1 Answers1

0

All the Chrome methods are asynchronous, which means that they just queue up the code to be called later.

Also note that tabs.getSelected has been deprecated, so I'm using tabs.query({active: true}... instead.

The callback fires out of order, after everything else has finished:

var currentTab;                   // 1

chrome.tabs.query({active: true}, // 2, queues up callback and continues
    function(tabs) { 
        currentTab = tabs[0].url; // 4, last, after everything else
    });

console.log(currentTab);          // 3 callback hasn't fired yet, so undefined

Welcome to what's sometimes called 'callback hell'.

The easiest way around this is to use an asynchronous or promise wrapper library like chrome-extension-async. This let's you use async/await syntax:

async function yourCode() {
    try {
       const currentTabs = await chrome.tabs.query({active: true});
       const currentTab = currentTabs[0];
       console.log(currentTab);
    }
    catch(err) {
        // Log errors etc
    }
}

You're still making a callback and executing code after it's finished, but now you can easily use variables before and after the await. I recently blogged about that in a lot more detail than will fit here.

Keith
  • 150,284
  • 78
  • 298
  • 434