与条件承诺链反应并在发送调度之前等待它们
React with conditional promises chain and wait for them all before send dispatch
我是新手。我有一个用户列表,该列表在组件安装时获取一次。
在将结果发送到 reducer 之前,它需要在用户列表中循环并从另一个端点获取用户 fullname/title,然后将新的 属性 添加到用户列表对象。
我不知道如何在调用调度之前等待所有承诺(getUserById() 函数)完成。我在这里尝试了解决方案,但失败了:
下面的代码只是为了说明我想要什么:
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.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
,因为您只是将 属性 添加到现有对象。这将在没有地图的情况下发生。
- 现在地图正被用于 return 您第二次 API 调用的承诺数组。
Promise.all
使用它来等待所有这些承诺解决。
我是新手。我有一个用户列表,该列表在组件安装时获取一次。
在将结果发送到 reducer 之前,它需要在用户列表中循环并从另一个端点获取用户 fullname/title,然后将新的 属性 添加到用户列表对象。
我不知道如何在调用调度之前等待所有承诺(getUserById() 函数)完成。我在这里尝试了解决方案,但失败了:
下面的代码只是为了说明我想要什么:
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.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
,因为您只是将 属性 添加到现有对象。这将在没有地图的情况下发生。 - 现在地图正被用于 return 您第二次 API 调用的承诺数组。
Promise.all
使用它来等待所有这些承诺解决。