内部承诺始终如一

问题描述 投票:1回答:1

我已经为这个问题折磨了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

请帮助我找到正确的解决方案或方向。

javascript asynchronous promise async-await react-admin
1个回答
1
投票

但是,在这种情况下,所有的诺言都是一次处理,而不是顺序执行,因此它们的页面加载时间非常长。

现在我正在尝试使用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; };
© www.soinside.com 2019 - 2024. All rights reserved.