函数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 } },
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('数据收集完毕'); },
这个问题是由于 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语句的修饰符,而不是常用表表达式的属性,因此您可以像这样使用它: