Javascript 如何使用等待映射(React)

Javascript 如何使用等待映射(React),javascript,reactjs,Javascript,Reactjs,所以问题是,即使我把wait放在commentList.map函数的前面,它仍然会执行下面的代码,我怎么能避免呢 输出: 然后是5F320724450B32620449657 然后是5F320724450B32620449657 设置状态5F320724450B32620449657之前 是否更新了5F320724450B32620449657 设置状态后 异步DummyPerson 由于这个问题,我没有在网页上显示用户名,而是显示ObjectId。鉴于您正在使用map,您可以等待通过Promi

所以问题是,即使我把wait放在commentList.map函数的前面,它仍然会执行下面的代码,我怎么能避免呢

输出
然后是5F320724450B32620449657
然后是5F320724450B32620449657
设置状态5F320724450B32620449657之前
是否更新了5F320724450B32620449657
设置状态后
异步DummyPerson


由于这个问题,我没有在网页上显示用户名,而是显示ObjectId。

鉴于您正在使用
map
,您可以等待通过
Promise获得的承诺数组。所有
map
上:

componentDidUpdate() {
    if (this.state.currentDirectory === Constant.EVENT_DISCUSSION_COMMENTS) {
      console.log("Did update", this.state.commentList[0].reply_by);
    }
  }

  handleGetDiscussionComments = async (e) => {
    const target = e.target;
    const discussionID = target.getAttribute("data-key");
    const currentDirectory = Constant.EVENT_DISCUSSION_COMMENTS;

    if (discussionID !== null) {
      const commentList = await CommentApi.getCommentBasedOndiscussion_id(
        discussionID
      );

      await commentList.map(async (comment) => {
        const username = await User.getUserName(comment["reply_by"]).then(
          console.log("then", comment.reply_by)
        );
        comment["reply_by"] = username;
        console.log("async", comment.reply_by);
      });

      console.log("before setState", commentList[0].reply_by);

      this.setState({
        commentList,
        selectedDiscussionID: discussionID,
        currentDirectory,
      });

      console.log("after setState");
    }
  };


你可以把东西重构成这样

  • 巨大的if被认为是减少筑巢的早期回报
  • 不必要的
    .then()
    已从注释用户名映射中删除
  • 此处添加了必要的
    Promise.all()
handleGetDiscussionComments=async(e)=>{
const target=e.target;
const discussionID=target.getAttribute(“数据键”);
const currentDirectory=Constant.EVENT\u DISCUSSION\u COMMENTS;
if(discussionID==null){
返回;
}
const commentList=wait CommentApi.getCommentBasedOndiscussion\u id(discussionID);
等待承诺(
commentList.map(异步(注释)=>{
comment[“reply_by”]=wait User.getUserName(comment[“reply_by”]);
}),
);
这是我的国家({
评论列表,
selectedDiscussionID:discussionID,
当前目录,
});
控制台日志(“设置状态后”);
};
改进 要详细说明(以前)我的最后一点:

进一步的改进是收集一组需要获取用户名的用户ID,并且只获取每个用户名一次

更好的是,您可能会在客户端缓存useridusername映射,因此当加载新注释时,您可能已经加载了用户名


我可以问一下为什么在地图前面使用“仅等待”不起作用吗?@Newbie承诺数组本身是不可等待的,因此它最终等同于
等待承诺。解决([承诺,承诺,承诺,…])
。你能详细说明最后一点吗?“我对这个领域很陌生,不太确定缓存的事情,但我想知道一些关于缓存的事情,如果它能帮助我改进更干净的代码确保的事情,”补充道。
await Promise.all(commentList.map(async (comment) => {
        const username = await User.getUserName(comment["reply_by"]).then(
          console.log("then", comment.reply_by)
        );
        comment["reply_by"] = username;
        console.log("async", comment.reply_by);
      }));
// Construct a set of unique user IDs
const userIdSet = new Set(commentList.map((c) => c.reply_by));
// Fetch an array of pairs [userid, username]
const userIdPairs = await Promise.all(
  [...userIdSet].map(async (userId) => [
    userId,
    await User.getUserName(userId),
  ]),
);
// Create a mapping out of it
const userIdMap = Object.fromEntries(userIdPairs);
// Augment comment objects with `reply_by_name` from the map
commentList.forEach((c) => (c.reply_by_name = userIdMap[c.reply_by]));
// a global variable (I know, usually not encouraged,
// but pragmatically should be fine,
// and can be refactored to something fancier later)
const knownUserNames = {};

// ...

async function handleGetDiscussionComments() {
  // Construct a set of unique user IDs
  const userIdSet = new Set(commentList.map((c) => c.reply_by));
  // Fetch an array of pairs [userid, username] unless we already know the result
  const userIdPairs = await Promise.all(
    [...userIdSet].map(async (userId) => [
      userId,
      knownUserNames[userId] || (await User.getUserName(userId)),
    ]),
  );
  // Create a mapping out of it
  const userIdMap = Object.fromEntries(userIdPairs);
  // Augment comment objects with `reply_by_name` from the map
  commentList.forEach(
    (c) => (c.reply_by_name = userIdMap[c.reply_by]),
  );
  // Update the global known username mapping with any new results
  Object.assign(knownUserNames, userIdMap);
}