async / await无法正常工作?

时间:2018-02-19 08:57:36

标签: javascript promise async-await firefox-webextensions

我正在尝试编写Foxfire Web扩展。我想要一个返回选项卡URL的函数。

Firefox标签browser.tabs.get(id)会返回一个承诺,该承诺会解析为包含具有该URL成员的标签对象。 browser.tabs.query返回一个promise,该promise将解析为包含选项卡ID的tabs数组。

计划将上面的两个调用包装在一个解析为tab.url的promise中 使用async / await等待它解析并返回结果。

根据MDN文件:

  

“await表达式导致异步函数执行暂停直到a   承诺得到履行,即解决或拒绝,并恢复   履行后执行异步功能。恢复时,   await表达式的值是履行的Promise的值。“

清单文件具有标签权限。

所以我的代码如下:

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)
      })
  })
}

如图所示,console.dir和console.log语句已被注释掉。我调试代码并使用命令行来执行测试功能。我(我显然是错的)认为测试函数中的await应该等到promise解析然后让我返回值。

好的,如果我取消注释console.log和console.dir语句,从命令行运行测试会得到预期的(url)结果。在控制台中,我看到了log / dir语句的结果,当从命令行运行时,最终结果是选项卡的URL(您可以从console.dir获取test.id for test2)。

如果我注释掉console.dir语句,我会在日志中看到一行“Promise {:”pending“}”,紧接着是新行上的所需结果(url)。

如果我然后注释掉console.log语句,我只能获得“Promise {:”pending“}”行。我从来没有得到所需的URL。

如果有人想尝试这个,那么清单文件就会出现:

{

  "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"
}

2 个答案:

答案 0 :(得分:2)

在文档中发现异步函数必须返回一个promise。任何退货声明。如上所示,将忽略不包含promise的return语句的值。显然,函数中的最后一个承诺被返回。

所以,据我所知,你不能写一个等待promise的函数返回该promise的值。

来自let xx = await promise的值,xx在await语句之后的同一函数中可用,并且可以在那里使用。因此,不是调用函数异步返回值,而是必须使调用函数异步并根据需要使用一系列等待来获取所需的值,然后在函数中使用它。

答案 1 :(得分:0)

尝试此操作,请记住,如果您有使用async / await的环境,则应优先使用.then()。

browser.browserAction.onClicked.addListener(test);

async function test() {
    let res = await GetActiveTabURL();
    return res;
}

async function test2(TabID) {
    let res = await GetTabURL(TabID);
    return res;
}

async function GetActiveTabURL() {
    const tabs = await browser.tabs.query({
        currentWindow: true,
        active: true
    });

    const tab = browser.tabs.get(tabs.pop().id);

    return tab.url;
}

async function GetTabURL() {
    const tab = await browser.tabs.get(TabID);

    return tab.url;
}