首页 文章

异步/等待无法正常工作?

提问于
浏览
2

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

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

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

根据MDN文档:

“await表达式导致异步函数执行暂停,直到Promise完成,解析或拒绝,并在执行后继续执行async函数 . 恢复时,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的test.id) .

如果我注释掉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"
}

1 回答

  • 1

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

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

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

相关问题