温馨提示×

JS代码中如何避免竞态条件

小樊
34
2025-12-25 02:50:08
栏目: 编程语言

在JavaScript中,竞态条件(Race Conditions)通常发生在异步操作(如setTimeoutsetIntervalPromiseasync/await等)中,当多个异步任务试图同时访问和修改共享资源时,可能会导致不可预测的结果。为了避免竞态条件,可以采取以下几种策略:

1. 使用同步机制

确保关键代码段在同一时间只能被一个任务执行。

let isProcessing = false;

function process() {
  if (isProcessing) return;
  isProcessing = true;

  // 执行关键代码
  console.log('Processing...');

  setTimeout(() => {
    isProcessing = false;
  }, 1000);
}

2. 使用锁机制

通过锁机制来控制对共享资源的访问。

class Lock {
  constructor() {
    this.isLocked = false;
  }

  async acquire() {
    while (this.isLocked) {
      await new Promise(resolve => setTimeout(resolve, 10));
    }
    this.isLocked = true;
  }

  release() {
    this.isLocked = false;
  }
}

const lock = new Lock();

async function process() {
  await lock.acquire();
  try {
    // 执行关键代码
    console.log('Processing...');
  } finally {
    lock.release();
  }
}

3. 使用Promise.all

当多个异步任务可以并行执行且结果不依赖于彼此的执行顺序时,可以使用Promise.all

async function processTasks(tasks) {
  const results = await Promise.all(tasks);
  console.log(results);
}

const tasks = [
  fetch('https://api.example.com/data1'),
  fetch('https://api.example.com/data2'),
  fetch('https://api.example.com/data3')
];

processTasks(tasks);

4. 使用队列

通过队列来控制任务的执行顺序。

class Queue {
  constructor() {
    this.tasks = [];
    this.isProcessing = false;
  }

  enqueue(task) {
    this.tasks.push(task);
    this.process();
  }

  async process() {
    if (this.isProcessing) return;
    this.isProcessing = true;

    while (this.tasks.length > 0) {
      const task = this.tasks.shift();
      await task();
    }

    this.isProcessing = false;
  }
}

const queue = new Queue();

queue.enqueue(async () => {
  console.log('Task 1');
});

queue.enqueue(async () => {
  console.log('Task 2');
});

queue.enqueue(async () => {
  console.log('Task 3');
});

5. 使用事件驱动编程

通过事件驱动的方式来处理异步操作,确保事件处理的顺序。

const EventEmitter = require('events');
const emitter = new EventEmitter();

emitter.on('task1', async () => {
  console.log('Task 1');
});

emitter.on('task2', async () => {
  console.log('Task 2');
});

emitter.on('task3', async () => {
  console.log('Task 3');
});

emitter.emit('task1');
emitter.emit('task2');
emitter.emit('task3');

通过以上策略,可以有效地避免JavaScript中的竞态条件,确保代码的正确性和可靠性。

0