I am trying to write a Foxfire web extension. I want a function that returns the URL of a tab.
Firefox tabs browser.tabs.get(id)
returns a promise that resolves to a tab object that has a member with the URL. browser.tabs.query
returns a promise that resolves to a tabs array which contains the id of the tabs.
Plan wrap the two calls above in a promise that resolves to the tab.url Use async/await to wait for it to resolve and return the result.
According to the MDN documentation:
"The await expression causes async function execution to pause until a Promise is fulfilled, that is resolved or rejected, and to resume execution of the async function after fulfillment. When resumed, the value of the await expression is that of the fulfilled Promise."
The manifest file has the tabs permission.
So my code is below:
browser.browserAction.onClicked.addListener(test);
async function test(){
let res = await GetActiveTabURL();
//console.log(`test ${res}`);
return res;
}
async function test2(TabID){
let res = await GetTabURL(TabID);
//console.log(`test2 ${res}`);
return res;
}
function GetActiveTabURL() {
return new Promise((resolve, reject) => {
browser.tabs.query({currentWindow: true, active: true})
.then((tabs) => {
browser.tabs.get(tabs.pop().id)
.then((tab) => {
//console.dir(tab);
resolve(tab.url)
})
})
})
}
function GetTabURL(TabID) {
return new Promise((resolve, reject) => {
browser.tabs.get(TabID)
.then((tab) => {
//console.dir(tab);
resolve(tab.url)
})
})
}
As shown the console.dir and console.log statements are commented out. I debug the code and use the command line to execute the test functions. I (and I am apparently wrong) think the await in the test functions should wait until the promise resolves and then let me return the values.
Ok if I uncomment the console.log and console.dir statements, running the test from the command line gives the expected (url)result. In the console I see the results of the log/dir statements and, when run from the command line the final result is the URL of the tab (you can get the tab.id from the console.dir for test2).
If I comment out the console.dir statements I get a line in the log that says, "Promise { : "pending" }" followed immediately by the desired result (the url) on a new line.
if I then comment out the console.log statements as well, I ONLY get the "Promise { : "pending" }" line. I NEVER get the desired URL.
the manifest file follows if anyone wants to try this:
{
"manifest_version": 2,
"name": "TestGetURL",
"description": "Functions returning the url",
"version": "1.0",
"icons": {
"48": "icons/link-48.png"
},
"permissions": [
"tabs",
"contextMenus",
"nativeMessaging",
"<all_urls>",
"webRequest",
"downloads",
"clipboardWrite",
"webNavigation",
"notifications",
"storage",
"cookies",
"alarms"
],
"background": {
"scripts": ["background-script.js"]
},
"browser_action": {
"browser_style":false,
"default_icon": {
"16": "icons/page-16.png",
"32": "icons/page-32.png"
}
},
"default_locale": "en"
}
Promise
constructor antipattern! – Bergiawait
does not make the code synchronous, it is still anasync function
that will return a promise. – Bergibrowser.tabs.get
– Jaromanda X