Writing Node code? What for?
If you’re coding your own web server, you’ve probably read that you should never use fs.readFileSync(): instead, you should use fs.readFile() and endure callback spaghetti.
I’ll add a corollary: if you aren’t coding your own web server, use fs.readFileSync().
Prefer synchronous code, when it’s an option. It’s faster and simpler. For instance, reading lots of small files:
In this example, synchronous code is 6–7 times faster than asychronous code.
Async pundits may protest. “Why not read the files in parallel?”, they’ll ask. (The answer: that causes EMFILE: too many open files — and it takes longer to generate that error message than it takes synchronous code to read all the files. A workaround would take lots more code, and it would still be slow.) Perhaps they’ll say, “But that isn’t real-world code!” … to which I’ll reply: I’ve observed dramatic real-world speedups and simplifications by switching to synchronous code.
When to use synchronous code
You have to make a decision every time you write a line of code. Sorry.
The basic question is: “should code run in the background while I’m reading this file?” If yes, use async. Otherwise, use sync.
It’s often a judgement call. Here are the basics:
Use sync for in-memory operations — async is a complete waste when you aren’t making blocking calls.
Use async when designing a library that makes blocking calls — unless you know all users want to use your library synchronously. You can add synchronous code as a feature once you’ve finished the async version.
Use async when a library you depend on forces async — because you have no choice. But consider contributing a synchronous version of the library.
Use sync for non-parallel tasks — such as computations or system-administration scripts.
In sum: async is often a mistake. Code appropriately.
Next up: streams.