Dealing with asynchronous execution is a big part of writing code nowadays, there are many different ways languages allow you to do this but I am a big fan of how node.js does it. Your code in node.js only executes in a single thread, this makes reasoning about it so much easier and it uses some simple mechanisms to make a single thread more than enough to run the average web server.
To do this any slow running operation you start will be run on another thread that you have no control over.
This would output "I happen before it is finished" before outputting "finished writing file". This is caused by the callback function being queued for execution on the main event loop as soon as the operation completes. One thing to be careful of is keeping your execution running, this will block anything else from happening in your code.
Because this loop keeps executing it stops the event loop from being able to run anything else and basically takes the web server down until you release control. This is why you should avoid using the sync methods that are provided by many APIs as they will block the event loop while they run.
So this is all well and good, and one of the things I like about this approach is it is reasonably simple to understand and get started using node.js. But as time goes on you will probably find some problems.
You can already see the way that this is going, most people call it callback hell, when the code just keeps indenting as you get more callbacks, and you can manage this by wrapping some of the functionality into your own functions but it can still be hard to manage. Especially when most of your functionality is orchestrating other slow-moving parts.
This doesn't really solve the problem in my opinion as it starts to make the flow of the code very hard to follow jumping around the file and also dealing with lots of callbacks. There is one other problem with the basic callbacks that you will most likely hit before long.
While this is better than some of the ways I have seen to achieve this, it's not particularly friendly to follow and it also executes once at a time, which is great if that's a requirement but not so good if it isn't.
I am by no way saying you shouldn't use callbacks, they are very simple and easy to get started within a new node.js application, but quickly you will probably want to start looking into promises (I'll cover these in a blog soon!). Personally, I usually start off with callbacks and migrate to promises when needed, slight inconsistencies don't worry me too much in this case, but as time goes on I do find the promise interfaces nicer for most things and am mostly using them.