2

I'm learning node.js atm, now I'm asking myself:

How "threadsafe" are normal Arrays?

Example:

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);
    }
});

If multiple of the Events are fired on the ee-Object, is there a chance, that the for Loop will fail because the indexes are already spliceed away?

Or said different: Is a way to ensure that the loop won't skip or fail because any elements that may be deleted by another callback call of the same event?

THX :)

jntme
  • 602
  • 1
  • 5
  • 18
  • 2
    Node.js is single-threaded, so your code can't be interrupted by another thread. But the above code is broken in that the way you're modifying the array during iteration will lead to sometimes skipping elements. – user94559 Aug 24 '16 at 06:32
  • I suppose that code is correct under the assumption that all the elements of the array are different. (You may skip an element, but only after you've found a matching element, meaning there are no more matching elements so you don't care.) – user94559 Aug 24 '16 at 06:34
  • you might want to have a look at http://stackoverflow.com/a/30906613/1048572 – Bergi Aug 24 '16 at 06:36

2 Answers2

1

node.js is single threaded and it does not interrupts sync execution.

Still, you're modifying the array while iterating it by its length which may lead to skipping elements. Also, your event is not prepared to be fired twice for the same array element.

martriay
  • 5,632
  • 3
  • 29
  • 39
  • Define "explode?" I'm pretty sure the worst case is that elements are skipped. – user94559 Aug 24 '16 at 06:35
  • @smarx well, if you have 10 elements, remove one in the 9th iteration, then will not find the 10nth element – martriay Aug 24 '16 at 06:36
  • The for loop will never reach the 10th element if the array gets shorter. (The condition `i < myArr.length` will fail before `i` reaches the value `9`.) – user94559 Aug 24 '16 at 06:37
1

I think we've covered the threading issue well, but you really should still address the loop. For an example of the "skipping" problem I'm talking about, try this:

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);
    }
}

Output:

1
2
4
5

Notice how the number 3 is never even seen by this loop.

One common way to fix this kind of loop so you can safely delete elements of the array while iterating over it is to go backwards:

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);
    }
}

Output:

5
4
3
2
1

Notice that we see all the elements of the array this way.

user94559
  • 59,196
  • 6
  • 103
  • 103
  • What I want to know is if there is a way to ensure that the loop won't skip or fail because any elements that may be deleted by another callback call of the same event. – jntme Aug 24 '16 at 08:19
  • About your answer: I haven't noticed that behaviour yet.. What is the difference looping through an array backwards than doing it the 'normal' way? – jntme Aug 24 '16 at 08:26
  • As I said, Node.js is single-threaded, so there's no way for another thread to interrupt you. As to why iterating backwards addresses the skipping issue, I encourage you to step through it by hand, paying attention to the values of `i` and the contents of the array. – user94559 Aug 24 '16 at 16:00