Search code examples
asynchronousgoogle-chrome-extensioncallback

How is async behavior useful if we have to await for the result to proceed?


Please pardon me if the question sounds weird but I have been curious about that. Let me illustrate further with an example. I am using a function below to extract the current tab URL in my chrome extension. The method which chrome supplies is async and I use a callback to extract the value, await till the process is complete and then use it ...

function addCurrentURL() {
  let url;
  function urlCallback(result) {
    url = result
  }

  await getTab(urlCallback);

  async function getTab(callback) {
    chrome.tabs.query(
      { active: true, lastFocusedWindow: true },
      function (tabs) {
        callback(tabs[0].url);
      }
    );
  }

  console.log(url)
}

As you can see, I am passing the function urlCallback to get the result and I am awaiting getTab async function (because chrome.tabs method is async) to wait for the result before I console it.

So how exactly is async helping me in this scenario as the code block next to it is waiting to execute for it to happen?

Also, please do let me know if there's a better way to do the operation above :)

Thank you for taking the time to explain this to me.


Solution

  • The advantage of using await with an asynchronous API is that your other code outside of this execution chain won't be blocked and DOM of the page won't be blocked while that API runs.

    However, you're doing it incorrectly.

    Here's how proper promisifying of a callback-based function looks like:

    async function addCurrentURL() {
      const url = await getActiveTabUrl();
      console.log(url);
    }
    
    function getActiveTabUrl() {
      return new Promise(resolve => {
        chrome.tabs.query({ active: true, lastFocusedWindow: true }, tabs => {
          resolve(tabs[0].url);
        });
      });
    }
    

    An even better/simpler approach is to use WebExtension polyfill so you can write this:

    async function getActiveTabUrl() {
      const tabs = await browser.tabs.query({ active: true, lastFocusedWindow: true });
      return tabs[0].url;
    }