## 问题描述
eg: 在数据量比较小,后台只提供了根据树 `父节点` 请求 `子节点` 的数据,此时就需要通过 `遍历` 的方式同步将数据处理为树状结构。但是我们会遇到遍历时无法按序获取数据的问题,像下面的例子
~~~
// http api
const getNodeByParentId = async (id) => {
// 模拟异步的一个方法,方便直观显示
// 随机生成 100 ~ 500 ms 的延迟
const time = Math.floor(Math.random() * 400) + 100;
return new Promise((resolve, reject) => {
try {
setTimeout(() => {
resolve(id);
}, time);
} catch (err) {
reject(err);
}
})
}
~~~
1. 定义一个数组
~~~
const treeData = [1, 3, 5];
~~~
2. 遍历数组,调用异步方法数组数组内容,发现每次返回的数据顺序可能都不一样
~~~
treeData.forEach(async item => {
console.log(await getNodeByParentId(item));
})
~~~
## 解决方案
1. 自调用式方法 for 循环
~~~
console.log(1);
await (async function () {
for (let i = 0; i < treeData.length; i++) {
const res = await getNodeByParentId(treeData[i]);
console.log(res);
}
})()
console.log(2);
~~~
2. for of (推荐)
~~~
console.log(1);
for (const item of treeData) {
const res = await getNodeByParentId(item);
console.log(res);
}
console.log(2);
~~~
3. map
> map 结合 promis可以实现异步等待; 但是 map 内部函数的执行顺序不是按照预期执行的,所以适合于不在内部处理一些逻辑
~~~
console.log(1);
await Promise.all(treeData.map(async id => console.log(await getNodeByParentId(id))));
console.log(2);
~~~