异步操作阵列时的副作用

问题描述:

我正在学习node.js atm,现在我在问自己:异步操作阵列时的副作用

“线程安全”是正常的数组?

例子:

var myArr = ["Alpha", "Beta", "Gamma", "Delta"]; 

ee.on('event', function(itemString) { 
    //Loop over an Array that could change its length while looping through 
    for(var i=0; i<myArr.length; i++) { 
     // delete the item out of the array 
     if(myArr[i] == itemString) 
      myArr.splice(i,1); 
    } 
}); 

如果多个事件是对EE-对象解雇,是有机会的话,for循环会失败,因为该指标已经spliceed了吗?

或者说不同:是否确保循环不会跳过或失败,因为任何可能被同一事件的另一个回调调用删除的元素?

THX :)

+2

Node.js是单线程的,所以你的代码不能被另一个线程中断。但是上面的代码被破坏了,因为在迭代过程中修改数组的方式会导致有时会跳过元素。 – smarx

+0

我想在假设阵列的所有元素都不同的情况下,代码是正确的。 (你可以跳过一个元素,但是只有当你找到一个匹配的元素后,这意味着没有更多的匹配元素,所以你不关心。) – smarx

+0

你可能想看看http://stackoverflow.com/ a/30906613/1048572 – Bergi

node.js是单线程并且它不中断同步执行。

但是,您正在修改数组,同时通过可能导致跳过元素的长度对其进行迭代。 此外,您的事件不准备针对相同的数组元素被触发两次。

+0

定义“爆炸?”我很确定最糟糕的情况是元素被跳过。 – smarx

+0

@smarx好吧,如果你有10个元素,在第9次迭代中删除一个,那么将不会找到第10个元素 – martriay

+0

如果数组变得更短,for循环永远不会到达第10个元素。 (条件'我 smarx

我认为我们已经涵盖了线程问题,但您仍然应该解决循环问题。对于“退出”的问题,我在谈论的一个例子,试试这个:

var a = [1, 2, 3, 4, 5]; 
for (var i = 0; i < a.length; i++) { 
    console.log(a[i]); 
    if (a[i] === 2) { 
     a.splice(i, 1); 
    } 
} 

输出:

1 
2 
4 
5 

注意如何3的数量甚至从来没有通过这个循环看到。

解决这种循环的,所以你可以安全地删除数组的元素,同时遍历它是倒着走的一种常见方法:

var a = [1, 2, 3, 4, 5]; 
for (var i = a.length - 1; i >= 0; i--) { 
    console.log(a[i]); 
    if (a[i] === 2) { 
     a.splice(i, 1); 
    } 
} 

输出:

5 
4 
3 
2 
1 

请注意,我们以这种方式查看数组的所有元素。

+0

我想知道的是,如果有一种方法可以确保循环不会跳过或失败,因为任何可能被同一事件的另一个回调调用删除的元素。 – jntme

+0

关于你的回答: 我还没有注意到这种行为呢..通过一个数组向后循环的差异比做'正常'的方式是什么? – jntme

+0

正如我所说,节点。js是单线程的,所以没有办法让另一个线程中断你。至于为什么向后迭代解决跳过问题,我鼓励你手工完成它,关注'i'的值和数组内容。 – smarx