【问题标题】:Async function not waiting even after using promise即使使用了 Promise,异步函数也不会等待
【发布时间】:2020-12-23 00:20:08
【问题描述】:

我正在使用 JS 进行 chrome 扩展。函数 chrome.history.search 是一个异步回调。由于它是异步的,因此我计划使用 promise 使其同步。我希望代码使用 chrome.history.search 将值分配给 url,然后将其推送到全局数组 lastEpisodeLink。还有另一个函数 findLastEpisodeLink 在多个标题上调用 findLastEpisode_helper。

我需要的输出序列是:
开始, 里面, 成功,
开始, 里面, 成功,...

但我得到的是:
开始,开始,里面,成功,里面,成功

当我在函数运行后检查数组 lastEpisodeLink 时,它显示不应该是空的。我该如何解决这个问题?

是的,我已经按照How do I return the response from an asynchronous call? 的答案进行了操作,但仍然没有解决它。如果您能帮助我修复此代码,那将非常有帮助。谢谢

function findLastEpisodeLink_helper(title) {

  console.log("start");
  var url;

  function onSuccess () {
    console.log('Success!');
    lastEpisodeLink.push(url);
  }

  var promise = new Promise(function(resolve, reject) {
    
    chrome.history.search(
     {
      'text': title,
      'maxResults': 1,
      'startTime': 0
     },

    function(historyItems) {

      console.log("inside");
      url = historyItems[0]["url"];
      resolve();

    });
  });
  promise.then(onSuccess);
}

调用它的函数

function findLastEpisodeLinks() {

  for(title in stringArray) { //psudo code

    findLastEpisodeLink_helper(title);
  }
}

调用它的函数如下,它本身就是一个异步回调,所有的调用都在这里完成。

chrome.history.search(
   {
  'text': '',
  'maxResults': 10000,
  'startTime': 0
   },

   function(historyItems) {

      var allHistoryText = [];
      var allHistoryUrl = [];

      for(var i=0; i<historyItems.length; i++) {
        allHistoryText.push(historyItems[i]["title"]);
        allHistoryUrl.push(historyItems[i]["url"]);
      }

      // some functions

      findLastEpisodeLinks();

      displayAll(finalAllSeries);
});

【问题讨论】:

  • Promise 是异步的。您究竟如何认为使用 Promise 会使其同步?
  • 我该如何解决这个问题,你能帮忙
  • 您可以在解析中传递 url,并且在成功时同样可以访问。它将解决空数组的问题。
  • 是的,它确实填充了数组,但它由对象 promise{fulfield} 填充

标签: javascript asynchronous google-chrome-extension promise callback


【解决方案1】:

我会这样做,


const lastEpisodeLink = [];

function findLastEpisodeLink_helper(title) {
  return new Promise(function(resolve) {
    chrome.history.search({
      'text': title,
      'maxResults': 1,
      'startTime': 0
     },function(historyItems) {
      var url = historyItems[0]["url"];
      lastEpisodeLink.push(url);
      resolve();
    });
  });
}


async function findLastEpisodeLinks() {
  for(var title in stringArray) { 
    await findLastEpisodeLink_helper(title);
  }
}

【讨论】:

  • 我尝试了代码,它没有解决它。数组保持为空
  • 我浏览了你的代码,你能在 for(var obj in finalAllSeries) { 之前在 findLastEpisodeLinks 函数中添加一个 console.log 并查看在 for 循环执行之前打印的内容吗?如果当时填充了数组finalAllSeries。此外,您需要在第 97 行的 findLastEpisodeLinks(); 之前添加 async。请阅读 async await 的工作原理。
  • 这个循环for(var obj in finalAllSeries) 工作正常,我可以向你保证。我无法在第 97 行添加异步或等待它说 Uncaught SyntaxError: Unexpected identifier
  • 在第 97 行使用 swait 表示错误 await 仅对异步函数有效,
【解决方案2】:

我认为您的主要问题是如何保持 for 循环中异步函数调用的顺序。为此,您只需要await findLastEpisodeLink_helper,以便循环等待直到它的承诺得到解决。

async function findLastEpisodeLink_helper(title) {
  console.log('start');
  var url;

  function onSuccess() {
    console.log('Success!');
    lastEpisodeLink.push(url);
  }

  await new Promise(function (resolve, reject) {
    chrome.history.search(
      {
        text: title,
        maxResults: 1,
        startTime: 0,
      },

      function (historyItems) {
        console.log('inside');
        url = historyItems[0]['url'];
        resolve();
      },
    );
  });

  onSuccess();
}

async function findLastEpisodeLinks() {
  for (title in stringArray) {
    //psudo code
    await findLastEpisodeLink_helper(title);
  }
}

【讨论】:

  • 嘿我试过你的代码,问题仍然存在,数组大小为0。代码链接gist.github.com/mightomi/12f0af3692d9dd91650122fdd4d280d9
  • @SwastikSingh 你不是awaiting findLastEpisodeLinks 函数。当您运行代码时,您会立即记录它。
  • 我试过了,但不知何故它说 await 只对异步函数有效,代码完全相同。
  • @SwastikSingh 您需要用异步函数(命名为initmain)包装该大语句并在其中使用await。而且,别忘了叫它)
【解决方案3】:

使用现代async + await 语法和Promise.all

function search(title) {
  return new Promise(resolve => {
    chrome.history.search({
      'text': title,
      'maxResults': 1,
      'startTime': 0,
    }, results => resolve(results[0].url));
  });
}

async function findLastEpisodeLinks(titles) {
  const results = await Promise.all(titles.map(search));
  console.log(results);
}

用法:findLastEpisodeLinks(['text a', 'text b', 'text c'])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-21
    • 2020-03-24
    • 2021-08-15
    • 2020-10-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 2021-01-06
    相关资源
    最近更新 更多