This is a question from substack's stream-adventure question set. Link to question and solution is here:
https://github.com/substack/stream-adventure/tree/master/problems/duplexer_redux
I don't understand how the "write" method could work correctly in the solution:
function write (row) {
counts[row.country] = (counts[row.country] || 0) + 1;
}
Specifically, is there any guarantee that "row" will be full record like below? Is it posssible that "row" could be partial record?
{"short":"OH","name":"Ohio","country":"US"}
Looking through the code, it appears that duplexer is setting stream.write to call the write function on the input writer (which in this example is the through instance). So when duplexer.write is called it's calling it's writer.write:
https://github.com/Raynos/duplexer/blob/6d6f4b5b85964f7037917a9a3b70659c6e152f21/index.js#L44-L48
function proxyWriter(methodName) {
stream[methodName] = method
function method() {
return writer[methodName].apply(writer, arguments)
}
}
Within through it uses the input write as the write variable if it's supplied:
https://github.com/dominictarr/through/blob/6f814a601b37db1f44113e56a1eaa0c32a33b0a2/index.js#L14
write = write || function (data) { this.queue(data) }
And when it's own stream.write function is called (stream is returned for the through), it calls write's instead:
https://github.com/dominictarr/through/blob/6f814a601b37db1f44113e56a1eaa0c32a33b0a2/index.js#L25-L28
stream.write = function (data) {
write.call(this, data)
return !stream.paused
}
So all of that to say, when write is called on the duplexer, it looks as though it calls your defined write function passing the arguments it received. So you should receive the entire argument each time.
Hope that makes sense?
Related
What does below syntax means?
connect(mapStateToProps, mapDispatchToProps)(Home)
I understand we are passing two arguments to a function, but what is the purpose of below one?
(Home)
It doesn't look like node but Redux and as in a comment not an ES6 thing.
What it is: Connect is a higher order (factory) function ie. it returns a function. And it is that returned function which is immediately called with Home
Take a look and an example of mock of connect below
function connect(param1, param2) {
return innerFunction (innerParam) {
console.log(`${param1} ${innerParam} ${param2}`)
}
}
connect('A','B')('precedes')
// outputs 'A precedes B'
Edit: Added an example.
A function can return a function, and you can call this returned function immediately.
For information and as already stated in comments, the fact of decomposing one function call into smaller like this one in your example is called currying and is a common practice in JavaScript (more info here : What is 'Currying'?)
This example might help you :
function function1(info) {
return function(innerParam) {
console.log(`Hello this function has info ${info} and has just been called with this param: ${innerParam}` )
}
}
function1('Bobby')('Alice');
// same as :
var bobbyFunction = function1('Bobby');
bobbyFunction('Alice');
This is useful to dynamically generate a function that depends on some parameter, but can still be called several time with some other changing parameters. Imagine this, for instance :
var bobbyFunction = function1('Bobby');
['Alice', 'Tommy', 'Johny'].forEach(name => bobbyFunction(name));
It's plain javascript. Function connect returns another function and code immediately calls it with parameter Home.
function first(f) {
return function second(s) {
console.log(f, s);
}
}
// this
first('one')('two');
// is same as this
var x = first('one');
x('two');
see this example:
connect(mapStateToProps, mapDispatchToProps)(Home)// just like code below
function f(){
//do something
}
function connect(a,b){
return f;
}
connect(mapStateToProps, mapDispatchToProps);//first,return f;
connect(mapStateToProps, mapDispatchToProps)(Home)//second,return f(home);
I have share variable between javascript function which is asynchronous. One of them is main thread and another is event based. I want to return value when event is completed.
This is the code:
completeExecution = false; // Shared Variable (Global Variable)
indexDBdata = {}; // Shared Variable (Global Variable)
function getPermission(key) {
var permission_data={};
if(exist_in_local) {
indexdbConnection.getRecordByKey('userPermission',permitKey,function(data){
indexDBdata=data; // Before its complete function return value
});
} else {
// make ajax call & its working fine
}
return permission_data;
}
//get Data from IndexedDB
getRecordByKey:function(tableName,key,readRecords){
if(isEmptyOrNull(readRecords)){
console.log("callback function should not be empty");
return;
}
if(isEmptyOrNull(tableName)){
console.log("table name should not be empty");
return;
}
var returnObj={};
var isSuccessfull=false;
if(this.dbObject.objectStoreNames.contains(tableName)){
var transaction=this.dbObject.transaction(tableName);
var objectStore = transaction.objectStore(tableName);
objectStore.get(key).onsuccess = function(event) {
returnObj=event.target.result;
};
**//Return object after this events compelte**
transaction.oncomplete = function(evt) {
completeExecution=true;
indexDBdata=returnObj;
readRecords(returnObj);
};
transaction.onerror = function(evt) {
completeExecution=true;
indexDBdata={status:'404'};
readRecords("Table Not found");
};
} else {
completeExecution=true;
indexDBdata={status:'404'};
readRecords("Table Not found");
}
}
Problem is while retrieving data from indexedDB it always returns {} (empty object). I want to synchronised event thread and main thread or wait for event to be completed. I don't want to directly manipulate DOM on callbacks I have to return value.
If you have solution to above problem or any other trick then please help me.
Thanks in advance.
I don't find the question very clear, but if I understand it, then you need to learn more about writing asynchronous javascript. In general, functions that call callback functions are void (they return an undefined value). If you want to use the results of two callback functions together, then you will want to chain them so that upon the completion of the first function, which calls its callback function, the callback function then calls the second function which then calls the second callback. So there are four function calls involved. You will want to place the processing logic within the context of the successive callback function, instead of continuing the logic outside of the function and trying to use its return value.
In other words, instead of trying to do this:
function a() {}
function b() {}
var aresult = a();
var bresult = b(aresult);
// processing of both a and b
You would want to try and do something like following:
function a(acallback) {
acallback(...);
}
function b(bcallback) {
bcallback(...);
}
a(function(...) {
b(function(...) {
// all processing of both a and b
});
});
I'm trying to extend the JS Number prototype to include a Ruby-esque ".times" method (the merits of this pursuit are an issue for another time).
Here is my code:
Number.prototype.times = function(doThis) {
val = +this;
while (val > 0 ) {
doThis();
val--;
}
}
If I try
5..times(console.log(1));
I get the following output:
foo
TypeError: undefined is not a function (evaluating 'doThis()')
Why does the loop work on the first iteration and fail on the second?
(note: the goal is to make the Number prototype extension such that calling it is highly expressive, intuitive, and reads more like natural language, like Ruby's .times method.)
Your Number.prototype.times function is written to take another function as argument (which you're then calling with doThis()).
However, when calling the times function, you're not passing another function as a parameter, but then return value of console.log(1) which will most likely be undefined (which you're then trying to call as a function, resulting in the undefined is not a function error).
Instead, pass a function that's calling console.log(1):
5..times(function() {
console.log(1);
});
Your function reminds me of libraries like underscore or lodash, which provide a lot of functions that let you make very succinct code.
Here is how I might implement this with lodash, which provides a _.times() utility function:
Number.prototype.times = function(cb) {
return _.times(+this, cb);
}
You could use the _.partial() to make it more readable than an explicit function() {} wrapper:
5..times(_.partial(console.log,"blah"));
Or, if you wanted to put the partial into your times function it could be a little more readable:
Number.prototype.times = function () {
return _.times(+this, _.partial.apply(this,arguments));
};
5..times(console.log,"blah");
// can still be used with an arbitrary function block:
5..times(function() { console.log("some other block"); });
Here is a jsfiddle example.
change to this:
Number.prototype.times = function(doThis) {
val = +this;
while (val > 0 ) {
doThis();
val--;
}
}
5..times(function () {console.log(1)});
I want to understand one thing about async module in node.js.
I have created a function that map an object from a form to a model object and return this object.
This object is a video with an array of tags.
My question is where can I return the video ? I know normally it is inside the async callback function but if I do that, the object returned is undefined.
Whereas If i return the video object at the end of the whole function, it works but it's not safe as I'm not sure, my async is finished...
By the way, I don't understand the callback function passed in argument to async.each and
called after video.products.push(tag); . What does this function do?
Regards
in my mapping.js :
exports.video = function(object) {
var video = new Video();
video.name = object.name;
video.products = [];
async.each(object.tags, function(tago, callback) {
tag = {
"name" : tago.name
}
video.products.push(tag);
callback();
} ,
function(err) {
if( err ) {
console.log('Error' + error);
throw err;
}
logger.debug("into async" + video);
}
);
logger.debug("end function " );
**//return video;**
}
in my video.js :
var video = mapping.video(object);
logger.debug(video); // return undefined
The simple answer is that you can't - at least not via easy or obvious approach. As its name suggests, async is a library for queuing up asynchronous function calls into the event loop. So your exports.video function simply kicks off a bunch of asynchronous functions, which execute one after the other on an unpredictable time-frame, and then returns immediately. No matter where you try to return your video object within the scope of your function calls which are instantiated by async, the exports.video function will already have returned.
In this case it doesn't really seem like you need asynchronous function calls for what you're doing. I'd suggest that you replace your use of async with something like Underscore's each method, which executes synchronously, instead.
http://documentcloud.github.io/underscore/#each
You'd need to define a callback for your exports.video function e.g..
exports.video = function(object, callback) {
// video code (snip)...
async.each(object.tags,
function eachTag(tag, done) {
// code run for each tag object (snip)...
done();
},
function finished(err) {
// code run at the end (snip)...
callback(thingThatsReturned);
});
};
...and call it like this:
var videoUtils = require('videoUtils');
var tags = getTags();
videoUtils.video({ tags: tags }, function(thingThatsReturned) {
// do something with 'thingThatsReturned'
});
By the way, I don't understand the callback function passed in
argument to async.each and called after video.products.push(tag); .
What does this function do?
The async.each function will call the 'eachTag' function above (2nd argument) for each item in your array. But because it's done asynchronously, and you might do something else async in the function (hit a database/api etc.), it needs to know when that function for that particular array item has finished. Calling done() tells async.each that the function has finished processing. Once all the functions are finished processing (they've all called done()), async.each will run the 'finished' function above (3rd argument).
This is pretty standard async stuff for Node.js, but it can be tricky to get ones head around it at first. Hang in there :-)
Edit: It looks like your code isn't doing anything asynchronous. If it was, then the above code would be the way to do it, otherwise the following code would work better:
exports.video = function(object) {
// video code (snip)...
if (Array.isArray(object.tags)) {
object.tags.forEach(function eachTag(tag) {
// code run for each tag object (snip)...
});
}
return thingThatsReturned;
};
...and call it...
var videoUtils = require('videoUtils');
var tags = getTags();
var thingThatsReturned = videoUtils.video({ tags: tags });
I'm trying to go through the source code for the node chat demo seen here. In the server.js file and fu.js file there is a function referenced as callback() seen here:
function loadResponseData(callback) {
if (body && headers && !DEBUG) { //if they already have value
callback();
return;
}...
but as far as I can tell this function is never defined and I cannot find it as a module function of node.js, a function of jquery or a standard function for javascript.
I think I understand how callback functions work but I'm not familiar with this call and it is used frequently enough in this app that I would like a firm understanding of what it is and where it comes from.
So my question is three fold:
1) where is the function based: (javascirpt, jquery, node.js, particular to this app)
2) where can I find the source code for this function?
3) how is this function interacting with the functions it is called in?
It is the argument of the loadResponseData function. If you call loadResponseData like this:
loadResponseData(function () {
res.writeHead(200, headers);
res.end(req.method === "HEAD" ? "" : body);
});
then callback() in loadResponseData will execute
res.writeHead(200, headers);
res.end(req.method === "HEAD" ? "" : body);
EDIT to clarify the question in comments:
You could say it's a feature of JavaScript. The important thing here is that JavaScript is a functional language: it has functions as a data type in their own right. Thus, you can save them in variables (and indeed, that's all every function name in JS is - a variable with a function as its content), and pass them along in an argument list (as is demonstrated here). There is nothing magical about the name callback - it could have as well been fn or whoopsie7. To demonstrate:
var doubleAndOne = function(a) {
return a * 2 + 1;
}
function doItTwice(k, whoopsie7) {
whoopsie7(whoopsie7(k));
};
doItTwice(5, doubleAndOne); // result is 23
function(...) {...} is called an anonymous function: it is pure function value, taking some arguments and doing something with them, but it is not assigned to any name. To make a function with a name, you can assign this to a variable, or pass it as a parameter, just like you could with any other value. For example, there is very little difference between:
var five = function() { return 5; };
var doubleFuncValue = function(fn) { return fn() * 2; };
doubleFuncValue(five); // result 10
and
var five = 5;
var doubleNumValue = function(n) { return n * 2; };
doubleNumValue(five); // result 10