与条件承诺链反应并在发送调度之前等待它们
Posted
技术标签:
【中文标题】与条件承诺链反应并在发送调度之前等待它们【英文标题】:React with conditional promises chain and wait for them all before send dispatch 【发布时间】:2021-05-10 06:16:35 【问题描述】:我是新来的反应。我有一个在组件安装时获取一次的用户列表。 在将结果发送到reducer之前,它需要在用户列表中循环并从另一个端点获取用户全名/标题,然后向用户列表对象添加一个新属性。 我无法弄清楚如何在调用调度之前等待所有承诺(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
);
, []);
【问题讨论】:
【参考方案1】:您可以使用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
,因为您只是将属性添加到现有对象。这将在没有地图的情况下发生。
现在地图被用于为您的第二个 API 调用返回一组承诺。 Promise.all
使用它来等待所有这些承诺解决。
【讨论】:
哇,它的工作原理,非常感谢!之前一直没有真正理解 Promise 的机制,现在明白多了。以上是关于与条件承诺链反应并在发送调度之前等待它们的主要内容,如果未能解决你的问题,请参考以下文章