遍历一个 id 数组并每次发出一个单独的请求

Loop over an array of ids and make a separate request each time

我有一个这样的 api 端点,我需要向该端点发出放置请求。

   api/user-group/{id}/invite/{userId}

我遇到的问题是我的表单包含一个多列表,react select 列表允许用户 select 任意数量的组,所以每次用户 select 是一个组我将组 ID 存储在本地状态,但我的 api 端点只接受一个组 ID。我认为解决方案过于循环组 ID 并执行单独的请求。有人可以指导我如何实现这个解决方案还是有更好的解决方案?

我的代码:

    const AddUserToGroupPage = () => {
       const [currentUserId, setCurrentUserId] = useState('');
       const [GroupIds, setGroupIds] = useState([]); 

       const { inviteUserToGroup } = useUserGroupApi();


      const InviteExistingUser = async () => {
        const body = {};
        const res = await inviteUserToGroup({
          id: groupIds,
          body,
          userId: currentUserId,
        });
        return res;
      };

      const onGroupsSelected = (selected) => {
        if (selected) {
          setGroupIds(selected.map((select) => select.value));
        }
      };

      return (
            <>
              <Select
                name="userGroups"
                label="User Groups"
                placeholder="Select as many groups as you want"
                id="userGroups"
                defaultOptions
                options={groups}
                isMulti
                onSelectChange={onGroupsSelected}
            />
         </>
)
    }

我想你可以这样实现你想要的:

const InviteExistingUser = async () => {
    const body = {};
    return await Promise.all(
        groupIds.map((groupID) => {
            return inviteUserToGroup({
                body,
                id: groupID,
                userId: currentUserId,
            });
        }),
    );
};

在此代码中,对 groupIds.map() 的调用将 return 一个 Promise 列表,每个 Promise 解析为对 inviteUserToGroup 调用的 return 值(一个结果对于每个组 ID)。

然后您可以将该列表传递给 Promise.all,其中 return 是一个解析为结果列表的 Promise。所以基本上你从Promise<result>[](一个承诺列表)到Promise<result[]>(一个列表的承诺)。

然后您可以 await 该 Promise,此时您最终会得到所有对 inviteUserToGroup.

调用的结果列表

您有 3 个选择:

1。每次触发一个请求

GroupIds.forEach(g => {
  const body = {};
  const res = await inviteUserToGroup({
    id: g.id,
    body,
    userId: currentUserId,
  });
  // save response
  setGroupsInfo(prev => [...prev, res]
})

2。一起触发所有请求

const requests = GroupIds.map(g => {
  return inviteUserToGroup({
    id: g.id,
    body,
    userId: currentUserId,
  });
})

Promise.all(requests).then(resArray => {
  setGroupsInfo(resArray)
})

3。触发一堆(可能是 5 个)请求,等到它们结束,然后再触发一个,依此类推..

// take 5 each time
for(let i = 0; i < GroupIds.length; i += 5){
  const subGroupsIds = GroupIds.slice(i, i + 5);
  
  // fire 5 requests
  const requests = subGroupsIds.map(g => {
    return inviteUserToGroup({
      id: g.id,
      body,
      userId: currentUserId,
    });
  })

  // wait for the 5 requests
  const resArr = await Promise.all(requests);
  setGroupsInfo(prev => [...prev, ...resArr]);
}

第二个选项是最糟糕的,因为你可能有很多组,而你不能同时请求所有的组。

第三个选项是最佳选项,但它的实现并不直接。

第一个选项很简单,但在大量组上会很慢。