我已经为这个问题折磨了2天,但不敢问这个问题。我阅读了很多有关Promise和异步函数的文档。也许这个问题的答案将对其他用户有用。
我想在项目列表中调用详细项目的详细信息。
list
数组看起来像这样:
[
{
"id": 1,
"name: "A",
},
{
"id": 2,
"name: "B",
},
...
]
我想在one
数组中调用的list
数据:
{
"id": 1,
"url: "aaa",
"props": ["a", "a", "a"]
}
react-admin承诺:
const list = dataProvider.getList(resource, params);
const one = (id: number) => dataProvider.getOne(resource, { id })
[dataProvider
返回带有data
属性的对象的承诺。
我写了一个并行返回数据的函数:
const data = async () => {
const list = await dataProvider.getList(resource, params);
const one = (id: number) => dataProvider.getOne(resource, { id });
list.data = await Promise.all(
list.data.map(async (item) => {
const itemOne = await one(item.id);
return {
...item,
custom: {
test: itemOne.data.url,
},
};
})
);
return list;
};
console.log(data())
但是,在这种情况下,所有的诺言都是一次处理,而不是顺序执行,因此它们的页面加载时间非常长。
现在我是trying,要使用reduce
而不是map
。
请帮助我找到正确的解决方案或方向。
但是,在这种情况下,所有的诺言都是一次处理,而不是顺序执行,因此它们的页面加载时间非常长。
现在我正在尝试使用reduce而不是map。
不大可能以串行方式(一个接一个)而不是并行地(像现在这样)来进行操作;很可能会使页面加载花费longer。但是,如果您要依次(一个接一个)而不是并行地(全部同时发生)进行这些操作,则reduce
为此(以及几乎其他所有操作)过于复杂。只需使用for-of
循环即可。我在答案的末尾提供了一个示例。
我还没有使用react-admin,但是每当从API逐一获取一堆东西很慢时,我就会查看是否可以一次全部请求它们。查看the documentation,可以使用getMany
代替getOne
。像这样的东西:
const data = async () => {
// Get the list
const list = await dataProvider.getList(resource, params);
// Get the items
const items = await dataProvider.getOne(resource, { ids: list.data.map(({id}) => id) });
// Extracting each `id` from the item to create the array −−−−−−−−−^^^^^^^^^^^^^^^^^
// Add those to the list items
list.data = list.data.map((item, index) => {
return {
...item,
custom: {
test: items.data[index].url,
},
};
});
return list;
};
注意,假设从getMany
返回的数据与ids
数组的相同顺序。该文档似乎在示例中提出了建议,但遗憾的是实际上并没有say它。
[如果事实证明它没有按照您要求的顺序提供给您,您可能要制作一个以id
为键的地图:
const data = async () => {
// Get the list
const list = await dataProvider.getList(resource, params);
// Get the items
const items = await dataProvider.getOne(resource, { ids: list.data.map(({id}) => id) });
// Extracting each `id` from the item to create the array −−−−−−−−−^^^^^^^^^^^^^^^^^
// Build the map of those items keyed by `id`
const map = new Map(items.data.map(item => [item.id, item]));
// Add those to the list items
list.data = list.data.map((item, index) => {
return {
...item,
custom: {
test: map.get(item.id).url,
},
};
});
return list;
};
这里是for-of
循环依次进行的工作,但同样,我认为这很可能会导致问题[[更糟,而不是更好。
const data = async () => {
const list = await dataProvider.getList(resource, params);
const data = [];
for (const item of list.data) {
const itemOne = await dataProvider.getOne(resource, { id: item.id })
data.push({
...item,
custom: {
test: itemOne.data.url,
},
});
}
list.data = data;
return list;
};