【问题标题】:for-loop in for-loop doesn't execute in order with async/await functionfor-loop 中的 for-loop 不使用 async/await 函数按顺序执行
【发布时间】:2020-11-05 16:08:26
【问题描述】:

我有一个循环(索引为 j)在一个循环(索引为 i)中,其中有一个等待函数,调试后,我发现有时一对 (i,j) 执行多次。我完全糊涂了-_-

谁能解释一下?非常感谢!

代码如下:

我将 searchFunc 添加到输入元素。

async function searchFunc() {
  let results = [];
  let notebooksP = await queryData(url1);
  notebooks = notebooksP.value;
  // debugger;
  for (let i = 0; i < notebooks.length; i++) {
    let noteIds;
    let noteIdsP = await queryData(urlBase + notebooks[i].id);
    noteIds = noteIdsP.value;
    debugger;
    for (let j = 0; j < noteIds.length; j++) {
      console.log("runing at i=", i, ", j=", j, );
      let noteContentsP = await queryData(urlBase + noteIds[j].id);
      let data = noteContentsP.value;
      // debugger;
      let content = data.content;
      let idx = content.search(key);
      if (idx != -1) {
        let res = {};
        res.notebookId = notebooks[i].id;
        res.noteId = noteIds[j].id;
        results.push(res);
        console.log("found at i=", i, " j=", j);
      }
    }
  }
function queryData(path) {
    return new Promise(function (resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.open('get', path);
        xhr.send(null);
        xhr.onreadystatechange = function () {
            if (xhr.readyState != 4) return;
            if (xhr.readyState == 4 && xhr.status == 200) {
                var ret = xhr.responseText;
                resolve({value: JSON.parse(ret)});
            } else {
                reject('error');
            }
        }
    })
}
const searchContent = debounce(searchFunc, 500);
searchBox.addEventListener('input', searchContent);

function debounce(fn, wait) {
    let timeout = null;
    return function () {
        if (timeout !== null) clearTimeout(timeout);
        timeout = setTimeout(fn, wait);
    }
}

【问题讨论】:

  • 你在哪里运行你的 searchFunc?
  • searchFunc 函数的开头添加console.trace('searchFunc was called')。我想你会发现你在飞行中同时有多个电话。 console.trace 会将调用堆栈转储到控制台。查看那个调用堆栈,看看谁调用了searchFunc 来解释这两个调用。 (我在你的成绩单中看到了两个)
  • 是的,它被监听器中的 setTImeout 函数调用了两次(我在问题中添加了一些代码以使其清楚),您能告诉我如何纠正吗?谢谢!

标签: javascript promise async-await


【解决方案1】:

如果您在每次按键时都触发搜索,则存在设计缺陷。这可能会导致响应排序等问题。但是,忽略此问题,解决您遇到的问题的一种简单方法是简单地阻止函数同时调用两次,使用变量来跟踪它的运行时间:

let searching = false;
async function searchFunc() {
  if (searching) {
    return;
  }
  searching = true;
  let results = [];
  let notebooksP = await queryData(url1);
  notebooks = notebooksP.value;
  // debugger;
  for (let i = 0; i < notebooks.length; i++) {
    let noteIds;
    let noteIdsP = await queryData(urlBase + notebooks[i].id);
    noteIds = noteIdsP.value;
    for (let j = 0; j < noteIds.length; j++) {
      console.log("runing at i=", i, ", j=", j, );
      let noteContentsP = await queryData(urlBase + noteIds[j].id);
      let data = noteContentsP.value;
      // debugger;
      let content = data.content;
      let idx = content.search(key);
      if (idx != -1) {
        let res = {};
        res.notebookId = notebooks[i].id;
        res.noteId = noteIds[j].id;
        results.push(res);
        console.log("found at i=", i, " j=", j);
      }
    }
  }
  searching = false;
}

【讨论】:

  • 不客气。如果答案对您有帮助,请点赞/标记为答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-29
  • 2023-04-07
  • 1970-01-01
  • 2022-11-20
  • 2023-03-27
  • 2019-07-01
  • 2013-09-02
相关资源
最近更新 更多