0

I have a (perhaps trivial) question. I am using Node.js package async, and particularly the async.each method (https://github.com/caolan/async#forEach).

Consider the following code:

var arrayOne=[];

async.forEach(arrayTwo, 
  function (item, callback){ 
    arrayOne.push(item); // push into arrayOne
    callback(); // the iterator has completed
  }, function(err) {
   // do something with arrayOne
}); 

Is arrayOne.push(item) safe?

3
  • 4
    I thought everything in node.js was thread-safe - it's a single threaded, event-driven paradigm, no? Commented Dec 18, 2014 at 21:12
  • That's what I also know. This is why I said that the question may be trivial. However, stuff which gets run async still makes me a bit confused.. Commented Dec 18, 2014 at 21:16
  • asynchronous operations are event driven, meaning they'll happen sometime in the future when the event occurs. If the main thread is occupied when the event takes place, the event handler waits for it to be freed. Commented Dec 18, 2014 at 21:24

1 Answer 1

2

So the answer is a bit subtle here. For this exact case, you will end up with arrayOne having the same items in the same order as arrayTwo, but this is more of a side effect of your sample code not being truly asynchronous and async.forEach not doing anything overly unexpected/clever. However, to make this truly reliable, you want to use an async function that guarantees order, which the letter of the contract of .forEach/.each does not. .each only guarantees that the worker function will get called once with each item in arrayTwo. It does not guarantee that it will start them all in order or wait for one to finish before starting the next, etc. If the author of async decided to start the worker functions in reverse order for some performance optimization, for example, that would change your side effects. So it's best not to rely on any behavior beyond what is explicitly guaranteed in the definition/docs for the async function. So, using something like async.series would give you a reliable way to do this and not get unexpected order in arrayOne at the end. Of course, the parallelism characteristics are now vastly different.

However, on a technical note, non of this involves the concept of "thread safety" as node only has a single execution thread. However, you end up with the same type of race conditions to think about when dealing with async code like this, so at the end of the day you can code race conditions in node just like you could in a multithreaded language.

The most helpful analogy I keep in mind is async code is ordering food by delivery. If you call 3 restaurants and order one pizza from each, that does not imply what order the deliveries arrive at your door.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the answer. My main concern here is not the order, rather if two functions edit the same position in arrayOne, e.g., if both are trying to push in arrayOne[0]. But as far as I understood, this is not a problems since node.js has truly only one thread.
Yes, there's no issue with calling arrayOne.push.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.