Here is the Class: http.Server documentation
[Q1]: Is function(request,response){...} the request Event's Listener?
[Q2]: if It is,from my understanding,whenever there is a request, the listener gets called?
[Q3]: According to the following,
Does it mean if I pass in a listener as a parameter, it will be registered on request event automatically?Can I pass in any function Object?
If I pass in function(request,response){...} ,is it the so called callback function when it's triggered by a request event?
Not quite sure about the definition of callback function
requestListener is a function you pass to the http.createServer() method. If you pass that function, then it will get called on every incoming request that the http server receives.
And, when it gets called, it will be called with two arguments, a request object and a response object in that order.
The requestListener function that you pass to http.createServer() is referred to as a callback function because you're passing a function that will get called back later by some other code.
Here's a simple example:
// Create an simple http server that knows about one request URL
var server = http.createServer(function(req, res) {
if (req.url === "/") {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('okay');
} else {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('not okay');
}
});
[Q1]: Is function(request,response){...} the request Event's Listener?
It is a callback function that is automatically registered for the request evnet and thus is called for every incoming http request.
[Q2]: if It is,from my understanding, whenever there is a request, the
listener gets called?
Yes.
[Q3]: Does it mean if I pass in a listener as a parameter, it will be
registered on request event automatically?
Yes.
Can I pass in any function Object?
Yes. You must declare the arguments appropriately as request and response in that order, but you can name those arguments anything you want. Their values are passed as the first and second arguments. The names of the arguments are whatever you choose to use in your function. A usual convention is to use (req, res) or (request, response) as this makes your code more recognizable to other node.js developers.
If I pass in function(request,response){...} ,is it the so called
callback function when it's triggered by a request event?
Yes.
Not quite sure about the definition of callback function
It is just a function that you pass as an argument to another function. It can be either a function named that is defined as a named function or it can be an inline anonymous function as shows in the example above. It does not matter which it is. It is called a callback function because it will be "called back" by some other code at some time in the future.
Related
I have this code which assigns a listener to the request object and when data comes, the function is executed. My question is, how the "chunk" variable is getting its value on the function call? Is this some kind of implicit assignment to the request object? I have seen similar patterns in JS but didn't really understand how they work. Any clarification will help.
request.on("data",function(chunk){
response.write(chunk.toString().toUpperCase()) ;
})
The code that emits the "data" event on the request object (inside of the request object) passes the chunk parameter to the event handler. Since the request object inherits from an eventEmitter, the code inside the request object that wants to announce the availability of some data does something like this:
request.emit("data", chunk);
That, then causes the event handler you registered for the "data" event to get called with chunk as the argument.
This is the same as any event handler in Javascript. The code that triggers the event sets the arguments for the event handler. You must declare an event handler function that has arguments that match what will be passed to it which you are doing here.
This is pretty much how callback functions work in Javascript. The system the calls the callback determines the arguments the callback will be sent. You then declare your callback to match that and register that callback with the system that will be calling it (sometime in the future). In this case, because it's an EventEmitter, you register it with .on(). In other cases, you might register it some other way (like with promises, you would use .then() or .catch()).
I understand the essence of callback functions in that the function is executed again after being passed as the parameter to another function. However, I'm confused as to where the variables inside the callback function come from as shown in the following node.js example:
router.get('/', function(req, res){
res.render('index', {});
});
How do the variables req and res get populated? An example explaining how I can just call res.render(...) without declaring res myself would be greatly appreciated.
They come from the same place they come from when a normal non callback function is invoked, at invocation time.
If you have this function,
function add (a, b) {
return a + b
}
You're fine with knowing that a and b come from when you invoke add,
add(1,2)
and it's the same principle with callbacks, don't let your brain get all twisted just because it's getting invoked later.
At some point the function you pass to router.get is going to be invoked, and when it does, it will receive req and res.
Let's pretend the definition for router.get looks like this
router.get = function(endpoint, cb){
//do something
var request = {}
var response = {}
cb(request, response) // invocation time
}
In the case of your example, it's just up to node to pass your function request and response whenever .get is invoked.
The whole point of the callback is that the invoked function calls it back.
In the case of router.get, it will insert the route (path, method, callback) in a lookup table; when a request comes in, Express will construct the response object, match the request's path and method against all the entries in the lookup table, take the callback from the matching entry and invoke callback(request, response) (passing the detected request and created response).
They get populated by whatever code is calling the callback. In your example, this is something inside the Express framework, though Express uses the node http library under the hood and adds additional functionality to the request and response objects provided by it.
But in code you write you can create a callback function signature that takes whatever params you want.
I'm currently learning about callbacks in Node and JavaScript in general and am getting confused by the following:
var request = require('request');
request('http://www.google.com', function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body) // Show the HTML for the Google homepage.
}
})
My question is this: How does the request function know what each parameter/argument is in the callback? Because I could effectively call the function callback with two parameters and skip out the error? How would the function know that the first parameter passed was the response and not the error, for instance?
Does it do checks on the types of each at runtime or? Thanks.
The programmer who wrote the request API decides the order of the parameters sent to the callback. There is no type checking at runtime. If you were to supply only two arguments in your callback signature, e.g.
function(response, body) {}
you would still be receiving the error object and the response -- only in this case, the variable named "response" would hold the error object, and the variable named "body" would hold the response. The input you would be skipping would be the third one you didn't supply, the body. The names of your parameters make no difference, it is their position in the function signature that determines what value they will be assigned.
By convention, in javascript callbacks, the first parameter of the callback normally represents the error object. It is not always written this way, but it is a best practice.
Possibile implementation of this function could be:
function request (url, callback) {
// doing something
callback (error, response, body);
}
The function will set the value of error, response and body parameters. I don't know how it's is implemented, but suppose that you pass a number for the url. A possibile implementation could be:
function request (url, callback) {
if (typeof url === 'number') {
// Suppose that error is an instance of Error
callback (new Error ('Url must be a string'), null, null);
}
// other stuff...
}
When you call the request() function, and provide a function as an argument, it calls that function internally (inside the module) and passes in it's own data as the arguments (which you then use to do various things). The data it passes in is data it generated itself, it's not data you're creating.
That is a callback.
There is a quetsion I answered a little while ago that goes more indepth as to why these modules are structured this way, see: npm's guidelines on callback errors
You are using a specific module my friend and callbacks are controlled in this case directly from it.
How the callback works for 'Request' module is matter of research. Check their documentation.
Someone please help me. I have been reading a lot of javascript documentation and fiddling with javascript.
I am able to use the functions but I don't quite get this essential syntactic jazz going on here
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(1337, 'myhost');
console.log('Server running at http://myhost:1337/');
I cant figure out why its okay to use req and res in the anonymous function above. It's like they live somewhere inside of http. They are not declared anywhere! They are made up variable names in an anonymous function that reference inner objects or something. It's crazy.
How does a callback function like this?
or like
stream.on('data', function(data){
// use data... i dont know where its coming from
// or how it got there, but use it
});
If you could post a small example that mimics this process and syntax or explain how these callback functions can work like this or how I can pass these undeclared variables into functions like this I would greatly appreciate it.
A similar example to the answer posted below.
var b = {
somefunction : function( data ){
var x = 100;
x = x+1; // 101
return data(x); // returns the callback function data w/ value x
}
};
b.somefunction(function(foo){
foo++; // 101 + 1
console.log(foo); // prints 102
});
The main issue is that Javascript is a functional language so you can pass functions as parameters to other functions. In other languages you may have experienced passing a pointer or handle to a function, for example. Consider a simple cases in which you have some math functions:
function add(a,b) {return (a+b)};
function subtract(a,b) {return (a-b)}:
Now I could create a new function:
function longWayAroundTheBarn(num1,num2,theFunc)
{
// invoke the passed function with the passed parameters
return theFunc(num1,num2);
}
And call it like this:
console.log(longWayAroundTheBarn(1,2,add));
> 3
Or even like this:
console.log(longWayAroundTheBarn(longWayAroundTheBarn(2,2,subtract),4,add);
> 4
Obviously this would be a silly use callbacks, but you can imagine generally that the ability to 'plug-in' a function this way can be pretty powerful.
Consider if you couldn't pass functions. This might be one way you would implement this:
function reallyLongWayAround(num1,num2,funcName)
{
if(funcName==='add')
return add(num1 ,num2);
else if (funcName === 'subtract')
return subtract(num1, num2);
}
You can imagine that besides being really tedious code to have to write and maintain, it's not nearly so powerful because the reallyLongWayAround function could only ever call code it knew about. By passing functions, my longWayAroundTheBarn doesn't care if I create new functions and pass it to it. Note that because of weak typing, it doesn't even need to care about the parameters it is passing. Maybe you want to implement something like
function businessDaysBetween(d1,d2)
{
// implementation left as a reader exercise
};
It would work just fine to call:
longWayAroundTheBarn(new Date(2014,1,15), new Date(2014,1,22),businessDaysBetween)
Returning to the specific case you raised, req and res are not 'local variables' as one answer indicates - they are called parameters or arguments. You aren't passing anything into them. They are being passed to you by the calling function. You could actually call them fred and barney if you wanted, although it would be a terrible idea. The main point is that they will be called populated with request and response objects.
You actually don't even have to have the parameters in your function signature, you could just have a callback as below, and make use of the second parameter passed to your function by reading the arguments array (Note, it's not actually an array but behaves similarly in many respects). This would be a terrible, terrible idea, but again, trying to illustrate the point.
var http = require('http');
http.createServer(function () {
arguments[1].writeHead(200, {'Content-Type': 'text/plain'});
arguments[1].end('Hello World\n');
}).listen(1337, 'myhost');
The req and res are actually local variables of the anonymous function.
I have an example below similar to the codes posted in your question.
// static class
var HelperClass = {
"doSomething" : function ( callback ) {
// do something here, for example ajax call to a server
var data = ajaxCallFromServer();
// return the data via callback
callback ( data );
};
};
// you codes here calling the HelperClass
// calling .doSomething method with an anonymous function callback
// that expects 1 parameter. This parameter is returned by the above
// code via callback ( data ). And in the anonymous function
// i called it as retData, you can call it whatever you like
HelperClass.doSomething( function ( retData ) {
// do soemthing with your retData here
});
You should use the documentation.
So for example for createServer, follow this page - http://nodejs.org/api/http.html#http_http_createserver_requestlistener
http.createServer([requestListener])# Returns a new web server object.
The requestListener is a function which is automatically added to the
'request' event.
Then, you check the 'request' event -
Event: 'request'# function (request, response) { }
Emitted each time there is a request. Note that there may be multiple
requests per connection (in the case of keep-alive connections).
request is an instance of http.IncomingMessage and response is an
instance of http.ServerResponse.
Regarding the stream, exactly same. The docs here - http://nodejs.org/api/stream.html#stream_writable_stream
Look for
Event: 'data'
The point is that http.createServer function takes an argument that is not a variable, but a function, if that makes sense. In javascript you can do that. And that function expects arguments that are specified in it's API. You can make it anonymous, like in your example, or declared like below:
function serverFunction(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}
var http = require('http');
http.createServer(serverFunction).listen(1337, 'myhost');
but in the end it does not matter, it just behaves accordingly to what is specified in its the API.
I'm totally new to javascript and have difficulty in understanding the meaning of the scripts. :( Hope someone can help me or give some advice, thaks! :)
I have a javascript in which it call Ajax function like:
callAjax('../team.cgi', 'POST', data, function(text)
In the ajax2.js it define the function callAjax like:
function callAjax(url, method, data, handler, waittime, timeout_func)
My question is what's the parameter function(text)?
function(text) is the beginning of the definition of an anonymous function. Presumably the call looks something like this:
callAjax('../team.cgi', 'POST', data, function(text)
{
// do something with text
});
The function defined between those brackets takes a variable, text, and does something with it. This is possible in JavaScript because functions are first-class citizens. They can be assigned to variables, defined anonymously, etc.
Typically, you'd say the handler parameter of the callAjax function is a callback. It's a function that will be passed certain arguments when the Ajax call completes. This is typical of asynchronous code.
The snippet above is functionally the same as this:
function doSomethingWhenAjaxCompletes(text) {
// do something
}
callAjax('../team.cgi', 'POST', data, doSomethingWhenAjaxCompletes);
The only difference in the first is that the function isn't defined with the name doSomethingWhenAjaxCompletes; it's defined anonymously instead.
Without seeing the context of the handler function my guess would be that this is the returned value from the ajax call. For example, if team.cgi in your example above returns an xml list of teams then I would expect the text parameter in the handler function to be that list.
When issuing AJAX requests, execution does not halt and wait for the response to come back. Instead, the request is send and execution continues. You simply provide what is called a "callback" function which is called when the AJAX response is returned. Typically, the callback function takes a single argument containing the response object or message that was returned as the answer to your AJAX request.
callAjax('../team.cgi', 'POST', data, function(text) {
console.log('Got a response!');
console.log(text);
}
This simply sends the request. At some time later (after a pause due to network latency) you will see the console log message appear, indicating that a response was received and the callback function meant for "handling" the response has been called.