how to create a callback function node js - node.js

I have a flag , named 'flag', and when this flag get's a specific value , I want to invoke a specific function.
anyone knows how to do that?

var EventEmitter = require("events").EventEmitter;
var flags = Object.create(EventEmitter.prototype);
Object.defineProperty(flags, "someFlag", {
get: function () {
return this._someFlag;
},
set: function (v) {
this._someFlag = v;
this.emit("someFlag", v);
}
});
flags.on("someFlag", callback);

Related

How to create a re-usable caching method while using node-cache

I'm using node-cache on my Node.JS & Express web service. But after a while, I've got a bunch of similar logics cluttering, like these:
let data = this.cache.get('some-key')
if (data) {
return shopInfo
} else {
data = someModel.find(id)
this.cache.set('some-key', data)
return data
}
I Googled about it and found a possible solution here. But I don't wanna pass a callback function every time. Is there a better way? Or how can I modify it to utilize async/await instead of callback function?
get(key, storeFunction) {
const value = this.cache.get(key);
if (value) {
return Promise.resolve(value);
}
return storeFunction().then((result) => {
this.cache.set(key, result);
return result;
});
}
You're going to need a callback or promise as a parameter. Here's perhaps an easier way:
Helper function:
get(key, retrieveData) {
const value = this.cache.get(key);
if (value) {
return value;
}
const data = retrieveData()
this.cache.set(key, data);
return data;
}
Then you can use:
const result = get('some-key', () => someModel.find(id))
return result
Despite using a callback, it's still clean. No need to complicate your code with promises if you don't need them.
if you dont want to past callback every time, you can do opposite - modify callback itself.
// simple memoized...
function memoized(cache, fn) {
return async key => cache.has(key) ? cache.get(key) : cache.set(key, await fn(key)).get(key);
}
// some model handler...
function fetchFunction(key) {
console.log('call fetchFunction');
return Promise.resolve(key + '_value');
}
// modify callback...
// example: model.fetchFunction = memoized(new Map(), model.fetchFunction).bind(model);
fetchFunction = memoized(new Map(), fetchFunction);
// test...
(async () => {
console.log(await fetchFunction('test'));
console.log(await fetchFunction('test'));
})()

Passing a global reference to a function using Q in nodejs

Can some one explain this to me ... have a global object and using some promises as below. When I reference the global in my function directly the reference is correct. When I try pass the reference it is not.
var globalObj = { ... }
function one() {
var deferred = Q.defer();
...
deferred.resolve();
...
return deferred.promise;
}
function two {
var deferred = Q.defer();
...
deferred.resolve();
...
return deferred.promise;
}
function doSomthing() {
var ref = globalObj; // this is ok
...
}
one().
.then(two)
.then(doSomething) // (1) this is ok it works
the alternative is ...
var globalObj = { ... }
function one() {
var deferred = Q.defer();
...
deferred.resolve();
...
return deferred.promise;
}
function two {
var deferred = Q.defer();
...
deferred.resolve();
...
return deferred.promise;
}
function doSomthing(someRef) {
var sref = someRef; // someRef is []
...
}
one().
.then(two)
.then(doSomethhing(globalObj)) // (2) this is not ok does not work
Note that there are two versions of code listedI tried (1) passing no reference and this was fine and (2) passing a reference and this was not. I am not sure if this is a scoping issue or an issue with Q. Any ideas ?
This
one()
.then(two)
.then(doSomething(globalObj));
should be
one()
.then(two)
.then(function () {
return doSomethhing(globalObj);
});
because you don't want to call doSomething() immediately, but that's exactly what the first variant does.

Lifecycle of variable in AMD module

Below is the code which I saved as a file named listView.js. I wonder about how the inner variable working. For example, variable dtRngPckr is defined in the initialize within Backbone.View and whenever application move to the other part, I called onClose function to null the said variable. And when I need to reuse this module, there must be an error occur in render function. It triggered error not a function
define(function (require) {
"use strict";
var $ = require('jquery'),
_ = require('underscore'),
Backbone = require('backbone'),
dtRngPckr;
return Backbone.View.extend({
initialize: function (opt) {
dtRngPckr = require('daterangepicker');
},
render: function () {
dtRngPckr();
},
onClose: function () {
dtRngPckr = null;
}
});
});
Could someone tell me how's exactly this variable working
RequireJS caches the return value of a module so it only has to fetch it once, all prior variables are shared between the instances. To use a separate daterangepicker for each instance, you could attach it to your view:
return Backbone.View.extend({
initialize: function (opt) {
this.dtRngPckr = require('daterangepicker');
},
render: function () {
this.dtRngPckr();
},
onClose: function () {
this.dtRngPckr = null;
}
});

Asynchronous nodejs module exports

I was wondering what the best approach is for configuring a module export. "async.function" in the example below could be a FS or HTTP request, simplified for the sake of the example:
Here's example code (asynmodule.js):
var foo = "bar"
async.function(function(response) {
foo = "foobar";
// module.exports = foo; // having the export here breaks the app: foo is always undefined.
});
// having the export here results in working code, but without the variable being set.
module.exports = foo;
How can I export the module only once the async callback has been executed?
edit
a quick note on my actual use-case: I'm writing a module to configure nconf (https://github.com/flatiron/nconf) in an fs.exists() callback (i.e. it will parse a config file and set up nconf).
Your export can't work because it is outside the function while the foodeclaration is inside. But if you put the export inside, when you use your module you can't be sure the export was defined.
The best way to work with an ansync system is to use callback. You need to export a callback assignation method to get the callback, and call it on the async execution.
Example:
var foo, callback;
async.function(function(response) {
foo = "foobar";
if( typeof callback == 'function' ){
callback(foo);
}
});
module.exports = function(cb){
if(typeof foo != 'undefined'){
cb(foo); // If foo is already define, I don't wait.
} else {
callback = cb;
}
}
Here async.function is just a placeholder to symbolise an async call.
In main
var fooMod = require('./foo.js');
fooMod(function(foo){
//Here code using foo;
});
Multiple callback way
If your module need to be called more than once you need to manage an array of callback:
var foo, callbackList = [];
async.function(function(response) {
foo = "foobar";
// You can use all other form of array walk.
for(var i = 0; i < callbackList.length; i++){
callbackList[i](foo)
}
});
module.exports = function(cb){
if(typeof foo != 'undefined'){
cb(foo); // If foo is already define, I don't wait.
} else {
callback.push(cb);
}
}
Here async.function is just a placeholder to symbolise an async call.
In main
var fooMod = require('./foo.js');
fooMod(function(foo){
//Here code using foo;
});
Promise way
You can also use Promise to solve that. This method support multiple call by the design of the Promise:
var foo, callback;
module.exports = new Promise(function(resolve, reject){
async.function(function(response) {
foo = "foobar"
resolve(foo);
});
});
Here async.function is just a placeholder to symbolise an async call.
In main
var fooMod = require('./foo.js').then(function(foo){
//Here code using foo;
});
See Promise documentation
An ES7 approach would be an immediatly invoked async function in module.exports :
module.exports = (async function(){
//some async initiallizers
//e.g. await the db module that has the same structure like this
var db = await require("./db");
var foo = "bar";
//resolve the export promise
return {
foo
};
})()
This can be required with await later:
(async function(){
var foo = await require("./theuppercode");
console.log(foo);
})();
ES6 answer using promises:
const asyncFunc = () => {
return new Promise((resolve, reject) => {
// Where someAsyncFunction takes a callback, i.e. api call
someAsyncFunction(data => {
resolve(data)
})
})
}
export default asyncFunc
...
import asyncFunc from './asyncFunc'
asyncFunc().then(data => { console.log(data) })
Or you could return the Promise itself directly:
const p = new Promise(...)
export default p
...
import p from './asyncModule'
p.then(...)
Another approach would be wrapping the variable inside an object.
var Wrapper = function(){
this.foo = "bar";
this.init();
};
Wrapper.prototype.init = function(){
var wrapper = this;
async.function(function(response) {
wrapper.foo = "foobar";
});
}
module.exports = new Wrapper();
If the initializer has error, at least you still get the uninitialized value instead of hanging callback.
You can also make use of Promises:
some-async-module.js
module.exports = new Promise((resolve, reject) => {
setTimeout(resolve.bind(null, 'someValueToBeReturned'), 2000);
});
main.js
var asyncModule = require('./some-async-module');
asyncModule.then(promisedResult => console.log(promisedResult));
// outputs 'someValueToBeReturned' after 2 seconds
The same can happen in a different module and will also resolve as expected:
in-some-other-module.js
var asyncModule = require('./some-async-module');
asyncModule.then(promisedResult => console.log(promisedResult));
// also outputs 'someValueToBeReturned' after 2 seconds
Note that the promise object is created once then it's cached by node. Each require('./some-async-module') will return the same object instance (promise instance in this case).
Other answers seemed to be partial answers and didn't work for me. This seems to be somewhat complete:
some-module.js
var Wrapper = function(){
this.callbacks = [];
this.foo = null;
this.init();
};
Wrapper.prototype.init = function(){
var wrapper = this;
async.function(function(response) {
wrapper.foo = "foobar";
this.callbacks.forEach(function(callback){
callback(null, wrapper.foo);
});
});
}
Wrapper.prototype.get = function(cb) {
if(typeof cb !== 'function') {
return this.connection; // this could be null so probably just throw
}
if(this.foo) {
return cb(null, this.foo);
}
this.callbacks.push(cb);
}
module.exports = new Wrapper();
main.js
var wrapper = require('./some-module');
wrapper.get(function(foo){
// foo will always be defined
});
main2.js
var wrapper = require('./some-module');
wrapper.get(function(foo){
// foo will always be defined in another script
});

How to run a callback when all running in parallel function done their job?

I got stack with the question:
"How to run a callback after all async functions done their job"
Here an example:
function doTasks(**callback**) {
doTask1(function() {
...
});
doTask2(function() {
...
});
}
I do not want to run a task after another. The idea to run them in parallel, but I need that callback right after all done. Does nodeJs have build-in feature for it?
For now I'm using a combination of an EventEmitter and counter. Every time when a task is finished it runs an event. Because I know how many tasks have ran. I can count it and emit callback. But must be more flexible way. Here what I use now.
var EventEmitter = require("events").EventEmitter;
var MakeItHappen = module.exports = function (runAfterTimes, callback) {
this._aTimes = runAfterTimes || 1;
this._cTimes = 0;
this._eventEmmiter = new EventEmitter();
this._eventEmmiter.addListener("try", callback);
}
MakeItHappen.prototype.try = function () {
this._cTimes += 1;
if (this._aTimes === this._cTimes) {
this._cTimes = 0;
this._eventEmmiter.emit("try", arguments);
}
}
Is there another way to do it?
You can use the async library, https://github.com/caolan/async
async.parallel([
function(){ ... },
function(){ ... }
], callback);
Use a counter:
var a = function (cb){
//Asynchronous stuff
cb ();
};
var b = function (cb){
//Asynchronous stuff
cb ();
};
var remaining = 2;
var finish = function (){
if (!--remaining){
//a and b finished...
}
};
a (finish);
b (finish);

Resources