33

I need to write some modules that load data one time and then provide an interface to that data. I'd like to load the data asynchronously. My application already uses promises. Is providing a promise as the result of requiring a module a valid pattern/idiom?

Example Module:

var DB = require('promise-based-db-module');

module.exports =
  DB.fetch('foo')
  .then(function(foo){
    return {
        getId: function(){return foo.id;},
        getName: function(){return foo.name;}
    };
  });

Example Usage:

require('./myPromiseModule')
.then(function(dataInterface){
  // Use the data
});

UPDATE:

I've used this for a while now and it works great. One thing I've learned, and it's hinted at in the accepted answer, is that it is good to cache the promise itself, and whenever you want to access the data use then. The first time the data is accessed, the code will wait until the promise is resolved. Subsequent usage of then will return the data immediately. e.g.

var cachedPromise = require('./myPromiseModule');
cachedPromise.then(function(dataInterface){
  // Use the data
});
...
cachedPromise.then(function(dataInterface){
  // Use the data again somewhere else.
});
Tony
  • 953
  • 1
  • 10
  • 22
  • 1
    Looks like it would work well to me. – jfriend00 Sep 25 '15 at 03:52
  • 1
    Yes, seems perfectly fine. If you are using ES6 modules, you might even be able to use a promise-aware module loader, and `import` "synchronously". – Bergi Sep 26 '15 at 15:13
  • Did the answer below solve your issue? If so, please mark the best answer as the accepted answer by checking the green checkmark to the left of that answer to indicate to the community that your question has been answered and then both you and the person who provided the answer will earn some reputation points that can lead to more privileges here on StackOverflow. – jfriend00 Sep 27 '15 at 17:23

1 Answers1

12

This seems like a perfectly good interface for a module who's job is to do a one-time fetch of some data.

The data is obtained async so a promise makes sense for that. The goal is to fetch the data just once and then let all places this module gets used just have access to that original data. A promise works great for that too because it's a one-shot device that remembers its state.

Personally, I'm not sure why you need the getId() and getName() methods when you could just offer direct access to the properties, but either can work.

A downside to this interface is that there is no means of requesting a fresh copy of the data (newly loaded from the DB).

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Thanks! That's basically what I was thinking, but I wanted to make sure I wasn't off base. BONUS: I wonder if this is already done in the wild? I'll upvote the first (and maybe more) comment that links to a library in npm that does this (that was published before I wrote the question). – Tony Sep 28 '15 at 21:56
  • I added the accessors b/c I do not want to provide write access to the loaded data. It would probably be more idiomatic to just call them id and name. I may or may not have programmed in an unnamed language where that naming convention was standard. :) – Tony Sep 28 '15 at 21:59