返回

按钮切换时, 竟态引发的惊魂一幕

前端

开发中的按钮切换竟态问题

我在一个项目中遇到一个问题,页面上有按钮,按钮可以切换,切换后底下的内容会切换,这个内容是请求后台,后台返回的数据。

const button = document.querySelector('button');
const content = document.querySelector('.content');

button.addEventListener('click', () => {
  // 按钮切换
  button.classList.toggle('active');

  // 发送请求
  fetch('/data').then((res) => {
    // 获取数据
    const data = res.json();

    // 更新内容
    content.innerHTML = data;
  });
});

当我快速连续点击按钮时,页面上的内容会乱掉。这是因为当用户快速连续点击按钮时,可能会触发多个请求,这些请求可能会以不同的顺序返回,导致内容错乱。

竞态问题的根源

这个问题的根源在于竞态。竞态是指多个线程同时访问共享资源而引起的冲突。在我们的例子中,共享资源是后台的数据。当多个请求同时访问后台时,后台可能会以不同的顺序返回数据,导致内容错乱。

竞态问题的解决方案

为了解决这个问题,我们可以使用锁来控制对共享资源的访问。锁是一种同步机制,它可以确保只有一个线程可以同时访问共享资源。

let lock = false;

const button = document.querySelector('button');
const content = document.querySelector('.content');

button.addEventListener('click', () => {
  // 按钮切换
  button.classList.toggle('active');

  // 上锁
  lock = true;

  // 发送请求
  fetch('/data').then((res) => {
    // 获取数据
    const data = res.json();

    // 更新内容
    if (lock) {
      content.innerHTML = data;
    }

    // 解锁
    lock = false;
  });
});

通过使用锁,我们可以确保只有一个请求可以同时访问后台的数据,从而避免内容错乱。

总结

竞态问题是一个常见的问题,它可能会导致意外的 bug。为了避免竞态问题,我们可以使用锁来控制对共享资源的访问。锁是一种同步机制,它可以确保只有一个线程可以同时访问共享资源。