当前位置: 首页 > 知识库问答 >
问题:

javascript - 异步加递归问题,await被跳过?

巫马瀚漠
2023-11-07

函数recursive 是异步加递归
理想状态是:在函数updateParams调用 await函数recursive执行完后再执行后面代码。
实际:函数recursive还没执行完后面的代码就执行了


    async updateParams(type, keyword) {        if(this.treeData.length === 0) {          await this.recursive(this.vNode.childNodes)          console.log("��  updateParams  this.recursive��", this.treeData)        }        console.log('查找-');        const data = this.treeData.find(item => item.path === type)        this.setParams(data)        const query = Object.assign({}, this.params,{          current : 1,          size : 10000,          data : keyword        })        const res = await fetchPage(query)        this.ids = res.data.data.records.map(i => i.id)      },

 async recursive(data) {        try {          for (let i = 0; i < data.length; i++) {          const item = data[i]          if(item.isLeaf) {// 没有下级            const data = item.data ? item.data : item            this.treeData.push(data)          }else {            const { data } = await fetchArchiveTree(this.getQueryParams(item))            data.data.forEach(item => {              if(!item.isLeaf) {                const Arr = [item]                this.recursive(Arr)              }              this.treeData.push(item)            });          }        }        } catch (error) {          console.log('获取树形数据失败',error);        }        console.log('数据收集完毕');      },

getQueryParams(res) {    const data = res.data ? res.data : res    return {      id: data.id,      filter: data.filter || '',      path: data.path || '',      fondsCode: this.current_fonds    }  },

共有2个答案

晏弘雅
2023-11-07

recursive 方法内部实现的问题,Array 的 forEach 循环是不支持 async/await 的,所以应该把 forEach 部分换成 for 循环再配合 await ,如下:

 async recursive(data) {        try {          for (let i = 0; i < data.length; i++) {          const item = data[i]          if(item.isLeaf) {// 没有下级            const data = item.data ? item.data : item            this.treeData.push(data)          }else {            const { data } = await fetchArchiveTree(this.getQueryParams(item))            for (let item of data.data) {                if(!item.isLeaf) {                    const Arr = [item]                    await this.recursive(Arr)                }                this.treeData.push(item)            }          }        }        } catch (error) {          console.log('获取树形数据失败',error);        }        console.log('数据收集完毕');      },
嵇俊德
2023-11-07

这个问题是由于 JavaScript 的异步递归导致的。在函数 updateParams 中,this.recursive(this.vNode.childNodes) 被调用了,但是并没有等待它完成就执行了后面的代码。这是因为 JavaScript 的异步特性,当一个函数被标记为 async,那么它的所有异步操作都不会阻止后面的代码执行。

在你的代码中,递归调用 this.recursive(Arr)this.recursive(data) 完成之前就执行了,这就是为什么 console.log("�� updateParams this.recursive��", this.treeData) 在递归函数完成之前就被执行了。

要解决这个问题,你需要在 updateParams 函数中等待 recursive 函数完成。为了实现这一点,你需要将递归函数包装在一个 Promise 中,然后在 updateParams 函数中使用 await 来等待这个 Promise 完成。这样,后面的代码就不会在递归函数完成之前执行了。

下面是你可能需要修改的代码:

async updateParams(type, keyword) {    if(this.treeData.length === 0) {      await this.recursiveWrapper(this.vNode.childNodes)      console.log("��  updateParams  this.recursive��", this.treeData)    }    console.log('查找-');    const data = this.treeData.find(item => item.path === type)    this.setParams(data)    const query = Object.assign({}, this.params,{      current : 1,      size : 10000,      data : keyword    })    const res = await fetchPage(query)    this.ids = res.data.data.records.map(i => i.id)  },  recursiveWrapper(data) {    return new Promise((resolve, reject) => {      this.recursive(data).then(() => {        resolve()  // 当 recursive 完成时,调用 resolve()      }).catch(error => {        reject(error)  // 当 recursive 失败时,调用 reject()      })    })  },  async recursive(data) {    try {      for (let i = 0; i < data.length; i++) {      const item = data[i]      if(item.isLeaf) {// 没有下级        const data = item.data ? item.data : item        this.treeData.push(data)      }else {        const { data } = await fetchArchiveTree(this.getQueryParams(item))        data.data.forEach(item => {          if(!item.isLeaf) {            const Arr = [item]            this.recursive(Arr)  // 递归调用,但是不直接返回结果,而是等待 Promise 完成          }          this.treeData.push(item)        });      }      } catch (error) {        console.log('获取树形数据失败',error);      } finally {  // 使用 finally 来确保无论是否有错误,都能结束递归调用并返回结果        console.log('数据收集完毕');  // 这行代码会在所有的递归调用结束后执行一次,而不是在每个递归调用结束后执行一次。你可能需要调整这个代码来满足你的需求。        return Promise.resolve();  // 返回一个已经解决的 Promise,这样 recursiveWrapper 就可以等待这个 Promise 完成了。      }    } catch (error) {  // 这个 catch 块会在 recursive 函数抛出错误时执行。你可以在这里处理错误。      console.log('获取树形数据失败',error);  // 这行代码会在 recursive 函数抛出错误时执行一次。你可能需要调整这个代码来满足你的需求。
 类似资料:
  • 本文向大家介绍JavaScript异步加载问题总结,包括了JavaScript异步加载问题总结的使用技巧和注意事项,需要的朋友参考一下 同步加载的问题 默认的js是同步加载的,这里的“加载”可以理解成是解析、执行,而不是“下载”,在最新版本的浏览器中,浏览器对于代码请求的资源都是瀑布式的加载,而不是阻塞式的,但是js的执行总是阻塞的。这会引起什么问题呢?如果我的index页面要加载一些js,但是其

  • 假设我有以下内容: 然后我这样称呼它: 我省略了并且没有将声明为这一事实是否使它实际上是异步的? 我希望发生的情况是循环会立即完成,因为即使花费了很长时间,也不会被等待,并且会立即返回。 我认为这会导致文件内容在这样调用时被覆盖的问题,但这使我认为代码是以某种方式自动转换为同步代码的(尽管似乎不可能知道何时完成)。 那么,简单地说,从非异步方法调用函数是否会自动使代码同步执行,以及省略和(如在函数

  • 问题内容: 我有一个异步函数,要连续多次调用。问题是“多个”可以是几十万或数百万… 显而易见的方法是从回调中调用相同的函数,如下所示: 当然,涉及一些逻辑来停止递归。问题是堆栈是否充满了调用,并可能在某些时候导致堆栈溢出? 问题答案: 问题是堆栈是否充满了调用,并可能在某些时候导致堆栈溢出? 否。 如果调用回调是异步传递的,则不会堆积堆栈。 在您的代码中: 这是逐步发生的事情: 首先被称为。 然后

  • 理想的预期输出: start async sub end promisel async sub promise async end promise2 promise3 timeout 实际浏览器控制台输出为: start async sub end promisel async sub promise promise2 promise3 async end timeout 问题1:await后的代

  • 我现在正在做一个关于Collatz序列的问题。我必须找到最长的Collatz序列,如果我们从范围1开始,。。。,数字n的Collatz序列定义为:如果n mod 2==0,则下一个数字为n/2。如果n mod 2!=0那么下一个数字是3*n 1。n=10的顺序为10,5,16,8,4,2,1。 当然,如果我们用简单的方法来解决这个问题,我们会计算1,…,之间每个数字n的Collatz序列,。。。,

  • 问题内容: 此查询生成从1到4的数字。 但是,如果我对此进行修改, 它给 错误:“ z”处或附近的语法错误 我在这里做错了什么? 问题答案: 我认为这是因为RECURSIVE是WITH语句的修饰符,而不是常用表表达式的属性,因此您可以像这样使用它: