首页 > 解决方案 > fetch() 的行为不一致

问题描述

我正在开发一个类似于 Gmail 的电子邮件应用程序。为了加载所有电子邮件,我使用 fetch() 并且所有未归档的电子邮件都加载到网页上。同样,我使用 fetch() 将电子邮件标记为已归档/未归档。

 archive.addEventListener('click', e=>{
        if(e.target.innerHTML === "Archive"){
          fetch(`/emails/${element.id}`, {
            method: 'PUT',
            body: JSON.stringify({
                archived: true
            })
          })
        }
        else{
          fetch(`/emails/${element.id}`, {
            method: 'PUT',
            body: JSON.stringify({
                archived: false
            })
          })
        }
        e.stopPropagation();
        load_mailbox('inbox');
});

load_mailbox('inbox')获取收件箱中所有未归档的电子邮件。每当单击电子邮件上的存档按钮时,应加载收件箱,并且该特定电子邮件不应可见。但相反,我需要两次单击存档按钮才能正确加载收件箱。

为了解决这个问题,我添加了一个 1000 毫秒的超时,load_mailbox('inbox')并且效果很好。现在收件箱会正确,就像没有存档的电子邮件一样。

archive.addEventListener('click', e=>{
    if(e.target.innerHTML === "Archive"){
      fetch(`/emails/${element.id}`, {
        method: 'PUT',
        body: JSON.stringify({
            archived: true
        })
      })
    }
    else{
      fetch(`/emails/${element.id}`, {
        method: 'PUT',
        body: JSON.stringify({
            archived: false
        })
      })
    }
    e.stopPropagation();
    if(timeout) clearTimeout(timeout);
    timeout = setTimeout(()=>{load_mailbox('inbox')}, 1000);
  });

我无法理解为什么它需要超时和更清洁的方法来解决它。任何帮助,将不胜感激。

标签: javascriptevent-handlingfetch-api

解决方案


fetch是同步的 - 您的其余代码将在等待 http 请求完成时运行。听起来你只需要等待调用完成,一个简单的方法是让你的函数异步,然后await调用 fetch:

archive.addEventListener('click', async (e) => {
  e.stopPropagation();
  if(e.target.innerHTML === "Archive"){
    await fetch(`/emails/${element.id}`, {
      method: 'PUT',
      body: JSON.stringify({
          archived: true
      })
    })
  }
  else{
    await fetch(`/emails/${element.id}`, {
      method: 'PUT',
      body: JSON.stringify({
          archived: false
      })
    })
  }

  load_mailbox('inbox');
});

推荐阅读