这是递归调用Promise的案例,用于查询el-tree树形结构。之前是用懒加载做,导致接口只能一层一层的查,每次只返回一层数据,后面需要改成前几层通过接口多次查回来,方便搜索,那么在查的时候需要loading,多次查就要知道什么时候结束,这是第一版案例!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body></body>
<script>
function api() {
return new Promise((resolve, reject) => {
setTimeout(() => {
let arr = [{ name: "1" }, { name: "2" }];
resolve(arr);
}, 2000);
});
}
function recursivePromise(i = 0) {
// 递归的终止条件
if (i <= 0) {
return Promise.resolve(i);
}
// 返回一个Promise
return new Promise(async (resolve, reject) => {
await api();
console.log(`当前值为 ${i}`);
resolve(recursivePromise(i - 1)); // 递归调用
});
}
function get(i = 1) {
console.log(`第${i}轮开始`);
// 递归的终止条件
if (i == 2) {
return Promise.resolve(i);
}
i++;
return new Promise(async (resolve, reject) => {
const arr = await api();
// 使用.then获取最后的结果
recursivePromise(arr.length).then((res) => {
console.log(`第${i}轮结束`);
resolve(get(i));
});
});
}
get().then(() => {
console.log("终于完了!");
});
</script>
</html>
再来一版更符合业务场景的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body></body>
<script>
// 模拟异步请求,两次返回不一样的数据
function api() {
return new Promise((resolve, reject) => {
setTimeout(() => {
let arr = [{ name: "1" }, { name: "2" }];
resolve(arr);
}, 2000);
});
}
function api2() {
return new Promise((resolve, reject) => {
setTimeout(() => {
let arr = [{ name: "1" }, { name: "2" }, { name: "3" }];
resolve(arr);
}, 2000);
});
}
// 递归调用保证一层全部执行完成,把结果给上一层判断是否还要递归
let narr = [];
async function recursivePromise(arr, index = 0) {
if (index < arr.length) {
let res = await api2();
narr = [...narr, ...res];
index++;
console.log(`请求了 ${index}次`);
// 在处理完当前元素后,递归调用以处理下一个元素
return recursivePromise(arr, index);
} else {
// 所有元素都已处理完毕,返回一个 resolved Promise 给上级
return Promise.resolve(narr);
}
}
// 确定递归几层 i是要循环几层 这里i=2,因为模拟两层
function get(dataArr, i = 0) {
// 递归的终止条件
if ( i == 2) {
return Promise.resolve(i);
}
return new Promise(async (resolve, reject) => {
i++;
console.log(`第${i}轮开始`);
console.log(`第${i}轮有${dataArr.length}条数据`);
recursivePromise(dataArr).then((res) => {
console.log(`第${i}轮结束`);
console.log(`第${i}轮共返回了${res.length}条数据`);
resolve(get(res, i));
});
});
}
// 确定所以函数执行完
async function init() {
// 初始化查一次
const arr = await api();
get(arr).then(() => {
console.log("终于完了!");
});
}
init();
</script>
</html>