Just today I struggled with this very issue. The answer, it seems to me, is that meteor (or at least the iron router) doesn't handle async calls the way you'd expect. The solution is to wrap the async call into a fiber, which is the mechanism meteor uses to keep the programming synchronous.
In your case try this (sorry, I don't know coffeescript very well):
var Future = Npm.require('fibers/future');
...
var waiter = Future.wrap(fs.readFile);
var data = waiter('/tmp/a.txt').wait();
response.writeHead(200, {'Content-Type': 'text/plain'})
response.end(data)
EDIT Addressing the addition to the question.
Functions wrapped in a future need to have a callback as their last argument that has the (err, result) signature. Try this:
@getAccounts = (callback) ->
query = "SELECT Id, Name, AccountNumber FROM Account"
queryBySoql(query, (err, result)->
if err
return console.error(err)
return callback(err, result)
)