0

Is this the correct way to have asynchronous functions only run once within express? I don't want this function to have to run on every route. I'm looking for an express-friendly way to do this.

var packageJson = false
app.use(function(req, res, next){
  if(req.packageJson) return next()
  if(packageJson){
    req.packageJson = packageJson
    return next()
  }
  return fs.readFileAsync("./package.json", "utf8")
  .then(JSON.parse)
  .then(function(data){
    packageJson = data
    req.packageJson = data
    return next()
  })  
})

2 Answers 2

2

I wouldn't even run the asynchronous function from within the first call to that route, but just do

var packageJson = fs.readFileAsync("./package.json", "utf8").then(JSON.parse);
app.use(function(req, res, next){
  if (req.packageJson)
    return next();
  else
    packageJson.then(function(data){
      req.packageJson = data;
      return next();
    });
});

But don't forget proper error handling, if that packageJSON promise is rejected your route might hang infinitely.

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

4 Comments

Since it's a JSON file I would probably use require() :-)
@robertklep: Yeah, maybe, but require is not asynchronous. Oh, and it would do the caching for us as well, so this feels like cheating :-)
But it's read into memory just once, after that the data is being served from memory which is basically the same as "storing" the data in a promise value (I agree somewhat with it being cheating though, it's not a generic solution).
Indeed. I wanted to show how to do it with any generic asynchronous function. require might be the better option for this particular use case.
1

Just for reference (this is not a generic solution, @Bergi's is), in this particular case you can use require(), which has two useful features:

  • it can load JSON files directly
  • it will cache the file data in memory

The middleware would look like this:

app.use(function(req, res, next){
  req.packageJson = require('./package.json');
  return next();
});

The first request will take a small performance impact, as require() is synchronous, but for subsequent requests the data will be read from memory automatically.

Comments

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.