代码实现
let dataArray = [];
async function performOperation(operation, value) {
return new Promise((resolve, reject) => {
if (operation === 'add') {
dataArray.push(value);
resolve(dataArray);
} else if (operation === 'delete') {
const index = dataArray.indexOf(value);
if (index > -1) {
dataArray.splice(index, 1);
resolve(dataArray);
} else {
reject(new Error('Element not found for deletion'));
}
} else {
reject(new Error('Invalid operation'));
}
});
}
// 示例用法
performOperation('add', 1)
.then(result => console.log(result))
.catch(error => console.error(error));
performOperation('delete', 1)
.then(result => console.log(result))
.catch(error => console.error(error));
对防止竞争条件的理解
- 竞争条件:在并发编程中,竞争条件是指多个线程或进程在访问共享资源时,由于执行顺序的不确定性而导致程序出现不可预期的结果。在 JavaScript 数组的并发添加和删除操作场景中,可能会出现一个操作还未完成,另一个操作就开始执行,导致数据不一致,比如删除了未完全添加的元素,或者添加操作覆盖了本应删除的元素等。
- 防止竞争条件的方法
- 使用队列或顺序执行:在上述代码中,通过
Promise
和 async/await
将操作顺序化。每次操作都返回一个 Promise
,并且只有前一个操作完成(resolve
或 reject
)后,下一个操作才会开始,这样就避免了多个操作同时修改数组导致的数据不一致。
- 加锁机制:虽然 JavaScript 是单线程语言,但在 Node.js 环境下处理多进程或浏览器环境下使用
Web Workers
时,可以引入类似加锁的概念。比如使用一个标志变量表示当前是否有操作正在进行,只有当标志为空闲时,新的操作才能开始,操作完成后再释放标志。
- 使用不可变数据结构:在一些场景下,可以使用不可变数据结构,每次操作返回一个新的数据结构而不是直接修改原有的数据。这样可以避免多个操作直接修改同一数据带来的竞争问题,但这种方法可能在某些情况下性能开销较大,需要根据具体场景权衡。