Can someone give me some feedback on this pattern?
I am writing a node.js module that connects to a remote API, caches JSON, returns it as output. I have a cli wrapper script that uses the module, and then returns the output to a non-node app for a completely different purpose.
Am I using promises correctly here? Does anyone have any good module pattern + promises examples to look at? Is it proper to promisify a non-promise library and then wrap that library inside of a new promise when creating a function?
In this example saveJSON, cachedJSON, and refreshJSON all use fs or request so I am returning promises for those.
The lib is similar to this:
foo.js:
var Promise = require('bluebird')
var fs = Promise.promisifyAll(require("fs"))
var request = Promise.promisifyAll(require("request"));
function Foo() {
var json = {}
var emptyJSON = function() {
return {
"entries": {
"vars": {}
}
}
}
var saveJSON = function(json) {
return new Promise(function(resolve, reject) {
fs.writeFileAsync('foo.json', JSON.stringify(json))
.then(function() {
resolve(cachedJSON())
})
.catch (function(e) {
reject(e)
})
})
}
var cachedJSON = function() {
return new Promise(function(resolve, reject) {
fs.readFileAsync('./foo.json')
.then(JSON.parse)
.then(function(json) {
resolve(json)
})
.catch(SyntaxError, function(e){
// File exists, but has a syntax issue
reject("Invalid json")
})
.catch (function(e) {
// Return empty json on error
resolve(emptyJSON())
})
});
}
var refreshJSON = function() {
return new Promise(function(resolve, reject) {
request.getAsync('http://berkeleymapper.googlecode.com/svn-history/r101/trunk/web/foo.json').get(1)
.then(JSON.parse)
.then(saveJSON)
.then(function(json) {
resolve(json)
})
.catch (function(e) {
// Return empty json on error
resolve(emptyJSON())
})
})
}
return {
cachedJSON: cachedJSON,
refreshJSON: refreshJSON
}
}
module.exports = new Foo()
Where this could be utilized in a situation like this:
runFoo.js:
var foo = require("./foo")
// Refresh and return the latest json from remote
foo.refreshJSON()
.then(function(json) {
console.log('### Refresh cached json with remote and return ###')
console.log(json)
});
// Return only the cached json
foo.cachedJSON()
.then(function(json) {
console.log('### Return cached json only ###')
console.log(json)
});