You don't get to choose when to block. Blocking becomes an error which hangs the event loop. The only option for blocking calls is to use a thread pool that sends events back to the event loop when a thread finishes running.
You're right, I should've said "emulate blocking by checking that all of the tasks we queued have completed upon finishing a task before proceeding while allowing the event loop to run" instead of "blocking". It's not really blocking the event loop, only a controlling the flow of a particular path of execution. Only a few native API's provide synchronous versions that will block the entire process until they complete - like the filesystem API's fs.readFileSync.