我是新来的 react 。我有一个在组件安装时获取一次的用户列表。 在将结果分派(dispatch)到 reducer 之前,它需要在用户列表中循环并从另一个端点获取用户全名/标题,然后向用户列表对象添加一个新属性。 我不知道如何在调用调度之前等待所有 promise (getUserById() 函数)完成。我在这里尝试了解决方案,但失败了: How to return many Promises and wait for them all before doing other stuff
下面的代码只是为了说明我想要的:
const {
listUsers,
fetchUserData
} = useContext(GlobalContext);
const getUserById = async (userId) => {
return sp.web.siteUsers.getById(userId).get().then(user => user.Title);
}
useEffect(() => {
sp.web.lists.getById("8C271450-D3F9-489C-B4FC-9C7470594466").items.get()
.then(userLists => {
userLists = userLists.map(list => {
if (list.Person_x0020_ResponsibleId) {
getUserById(list.Person_x0020_ResponsibleId).then(username => {
list['Person_Responsible'] = username; // -> fetch user fullname and title
})
} else { // -> if id is null
list['Person_Responsible'] = '-';
}
return list
});
fetchListSuccess(userLists); // -> dispatch result to reducer
});
}, []);
最佳答案
您可以使用 Promise.all 来完成此操作。首先,您需要第二次 API 调用中的一系列 promise 。然后我们将这个数组赋予 Promise.all
,并且它将等待它们全部解析。
我用 async/await
重写了句法。它的工作原理与使用 .then
相同与 promise ,但是当您使用如此复杂的 promise 链时,使用 async/await
更容易遵循.
useEffect(async () => {
const userLists = await sp.web.lists.getById('8C271450-D3F9-489C-B4FC-9C7470594466').items.get();
const promises = userLists.map(async (list) => {
if (list.Person_x0020_ResponsibleId) {
const username = await getUserById(list.Person_x0020_ResponsibleId);
list.Person_Responsible = username; // -> fetch user fullname and title
} else { // -> if id is null
list.Person_Responsible = '-';
}
return list;
});
await Promise.all(promises);
fetchListSuccess(userLists); // -> dispatch result to reducer
}, []);
一些注意事项:
- 您确实不需要重新分配
userLists
在 map 中,因为您只是向现有对象添加属性。没有 map 也会发生这种情况。 - 现在,该映射用于为您的第二次 API 调用返回一组 promise 。这是由
Promise.all
使用的等待所有这些 promise 兑现。
关于javascript - 与条件 promise 链使用react并在发送调度之前等待它们全部,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66071174/