javascript synchronous asynchronous query [duplicate] - javascript

This question already has answers here:
I know that callback function runs asynchronously, but why?
(3 answers)
Closed 5 years ago.
I am new to Javascript.
Below nodejs code runs synchronously, I do not undestand, why?
var http = require("http");
var fs = require("fs");
http.createServer(function (request, response) {
// Send the HTTP header
// HTTP Status: 200 : OK
// Content Type: text/plain
response.writeHead(200, {'Content-Type': 'text/plain'});
// Send the response body as "Hello World"
response.end('Hello World\n');
}).listen(8081);
// Console will print the message
console.log('Server running at http://127.0.0.1:8081/');
var data = fs.readFileSync('input.txt');
console.log(data.toString());
console.log("Program Ended");
I got output as:
Server running at http://127.0.0.1:8081/
Tutorials Point is giving self learning content
to teach the world in simple and easy way!!!!!
Program Ended
Below nodejs code runs asynchronously, I do not understand, why? I agree there is a callback in the readFile function, so why it behaves asynchronously?
var http = require("http");
var fs = require("fs");
http.createServer(function (request, response) {
// Send the HTTP header
// HTTP Status: 200 : OK
// Content Type: text/plain
response.writeHead(200, {'Content-Type': 'text/plain'});
// Send the response body as "Hello World"
response.end('Hello World\n');
}).listen(8081);
// Console will print the message
console.log('Server running at http://127.0.0.1:8081/');
fs.readFile('input.txt', function(err, data){
console.log(data.toString());
});
console.log("Program Ended");
Here is the output:
Server running at http://127.0.0.1:8081/
Program Ended
Tutorials Point is giving self learning content
to teach the world in simple and easy way!!!!!
Could you please someone explain me clearly why above is behaving like that. Are callbacks always asynchronous? I also would like to know how execution happens internally for callback functions.
Assume a control came to the line readFile function (which is having callback in it), so why does control immediately executes another statement? If control transers to another statement, who will execute callback function? After callback returns some value, does control again comes back to same statement ie., 'readFile' line?
Sorry for stupid query.

The synchronous version (fs.readFileSync) will block the execution until the file is read and return the result containing the file contents:
var data = fs.readFileSync('input.txt');
This means that the next line of code will not be executed until the file is completely read and the result returned to the data variable.
The asynchronous version on the other (fs.readFile) hand will immediately return the execution to the next line of code (which is console.log("Program Ended");):
fs.readFile('input.txt', function(err, data) {
// This callback will be executed at a later stage, when
// the file content is retrieved from disk into the "data" variable
console.log(data.toString());
});
Then later, when the file contents is completely read, the passed callback will be invoked and so you see the contents of the file printed at a later stage. The second approach is recommended because you are not blocking the execution of your code during the file I/O operation. This allows you to perform more operations at the same time, while the synchronous version will freeze any other execution until it fully completes (or fails).

Related

nodeJs how to make http post request execute [duplicate]

This question already has answers here:
How to wait until a predicate condition becomes true in JavaScript?
(23 answers)
How to prevent Node.js from exiting while waiting for a callback?
(8 answers)
Closed 2 years ago.
I have narrow down my problem to this,
I want to send post request to an API server but the post request sent only after the program exits.
my main.js:
var request = require("request");
send_post_to_server = function(name, responseCallback, outconfig) {
var outconfig = outconfig || {...};
request.post({
url: 'http://localhost:3000/api/backtest',
json: outconfig
}, function optionalCallback(error, response, body) {
responseCallback(error, response, body);
});
}
send_post_to_server ('first post request', my_response_callback);
send_post_to_server ('second post request', my_response_callback);
while(true); // with the loop, the server never gets the post requests.
If I remove the while loop and the program exits, it dose work and I do get the response to optionalCallback and responseCallback. But with the loop, the server dose not get the request.
why is that happened? and how can I make the program send the request? some kind of flush?
to run the program I use:
node main.js and npm istall request for the request module.
Because while(true); is blocking the thread and Node.js using single thread. Prefer asynchronous to do the operation. See also: https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/
If you want to keep the Node.js process not terminating there is an answer for this
How to forcibly keep a Node.js process from terminating?

Accessing the data from a Node JS GET request without chaining callback functions

I'm using node.js simply so that I can run scheduled tasks and use GET requests. I'll paste some code that displays what I want to do, although it doesn't work for an obvious reason:
const http = require("http");
const request = require("request");
http.createServer(function (req, res) {
res.writeHead(200, {"Content-Type": "text/html"});
res.write("Hello, World!");
let a = getRequest();
console.log(a);
res.end();
}).listen(8080);
function getRequest() {
let b;
request("http://www.google.com", function(err, res, body) {
b = body;
})
return b;
}
So the b from the body does not work due to how the request is asynchronous and this leaves b as undefined when it is eventually printed. I know the way these callback functions are supposed to be used is to keep chaining of the callback function since that's the only place where the contents of body can be accessed. However, I don't want to keep chaining off functions because it completely destroys the structure of the program. I want to keep all my node server commands inside the http.createServer block. I don't want to place them in functions called from inside the callback function. In this example it doesn't really make sense for the process to be asynchronous since there's only 1 get request anyway and it can't be displayed in console.log until it's received anyway.
I just need a simple way to scrape data with get requests. What would be perfect is if I had some function that I could give a bunch of links, it gets the raw html from them, and then it waits for them to all be done so that I can process all the data at once.
How can something like this be implemented in Node.js?
You can do that using this module: sync-request.
With this module you will be able to make synchronous web requests from your NodeJS code.

Need help understanding Node.js in respect to routing using a JavaScript API?

I understand the basics of routing in Node.js and using the http module for it. I understand all the Node.js code below but just the JavaScript API part and how it is used to make the routing code much more cleaner is what I have trouble understanding. When I say "trouble understanding" I mean trouble understanding the syntax and how the routes object is used.
The code is from an E-book I have been learning from so please read the code below.
var http = require("http");
var url = require("url");
var route = {
routes : {},
for: function(path, handler){
this.routes[path] = handler;
}
};
route.for("/start", function(request, response){
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello"); response.end();
});
route.for("/finish", function(request, response){
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Goodbye");
response.end();
});
function onRequest(request, response) {
var pathname = url.parse(request.url).pathname;
console.log("Request for " + pathname + " received.");
if(typeof route.routes[pathname] ==='function'){
route.routes[pathname](request, response);
}else{
response.writeHead(404, {"Content-Type": "text/plain"});
response.end("404 Not Found");
}
}
http.createServer(onRequest).listen(9999);
console.log("Server has started.")
My understanding so far is that: route.routes is an empty object and route.for is a function. The function has two parameters function(path,handler) but I don't understand the part in the function i.e. this.routes[path] = handler;
From my understanding this.routes[path] is an empty object so is the code setting handler to an empty object?
and beyond this I have absolutely no clue what function onRequest(request,response){}; is doing.
Plase explain the whole code for me as I find it very disturbing not being able to understanding the basics before progressing through the E-book.
Http module that you include in first line has createserver function that takes a function as a parameter. In of the last lines we pass "onRequest" function to it. The function passed is internally invoked by http module whenever request is recived on port 9999 as also defined. Function onRequest is invoked with two parameters one is "request" that contains data like headers and body of a request that was recived. 2nd parameter is respons object it is whats sent back. It has functions that facilate this like writeHead which writes headers, .end which signals http module to sned the response finally back.
onRequest function can do whatever it wants with the request and send whatever response it wants to send back.
Here it using url module that is native to nodejs parses url and extract pathname which is everything after first / so www.mydomain.com/thispart/andthis...etc are extracted.
Then thus is done to do object lookup inside the routes. If object with key that is equal to string of this pathname exists it will return the value that is the function and if not the expression will evaluate to false and 404 part will be run. Upon match function gets invoked with response and request objects that onRequest got in the parameters.
In Javascript property of an object can be set even if its not present..
var a = {n:1};
a.x = "exists";
console.log (a.x); //exists

My http.createserver in node.js doesn't work?

Hello guys i just started learning node.js today and search a lot off stuff on the internet , then try to code in node.js i use these two codes to show me the same result but the last one is show the error on my browser something likes "can not find the page".So please explain to me why?
// JScript source code
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello World\n');
}).listen(1337, "127.0.0.1");
console.log('Server running at http://127.0.0.1:1337/');
This is working but
// Include http module.
var http = require("http");
// Create the server. Function passed as parameter is called on every request made.
// request variable holds all request parameters
// response variable allows you to do anything with response sent to the client.
http.createServer(function (request, response) {
// Attach listener on end event.
// This event is called when client sent all data and is waiting for response.
request.on("end", function () {
// Write headers to the response.
// 200 is HTTP status code (this one means success)
// Second parameter holds header fields in object
// We are sending plain text, so Content-Type should be text/plain
response.writeHead(200, {
'Content-Type': 'text/plain'
});
// Send data and end response.
response.end('Hello HTTP!');
});
}).listen(1337, "127.0.0.1");
This one is not working
Why?
The link of the last one that's not working
http://net.tutsplus.com/tutorials/javascript-ajax/node-js-for-beginners/
Thank you for all the answers, but i still don't understand about the problems.
the last one that is not working just has request.on?
request is an instance of http.IncomingMessage, which implements the stream.Readable interface.
Documentation at http://nodejs.org/api/stream.html#stream_event_end says:
Event: 'end'
This event fires when no more data will be provided.
Note that the end event will not fire unless the data is completely consumed. This can be done by switching into flowing mode, or by calling read() repeatedly until you get to the end.
var readable = getReadableStreamSomehow();
readable.on('data', function(chunk) {
console.log('got %d bytes of data', chunk.length);
})
readable.on('end', function() {
console.log('there will be no more data.');
});
So in your case, because you don't use either read() or subscribe to the data event, the end event will never fire.
Adding
request.on("data",function() {}) // a noop
within the event listener would probably make the code work.
Note that using the request object as a stream is only necessary for when the HTTP request has a body. E.g. for PUT and POST requests. Otherwise you can consider the request to have finished already, and just send out the data.
If the code your posting is taken literally from some other site, it may be that this code example was based on Node 0.8. In Node 0.10, there have been changes in how streams work.
From http://blog.nodejs.org/2012/12/20/streams2/
WARNING: If you never add a 'data' event handler, or call resume(), then it'll sit in a paused state forever and never emit 'end'.
So the code you posted would have worked on Node 0.8.x, but does not in Node 0.10.x.
The function you are applying to the HTTP server is the requestListener which supplies two arguments, request, and response, which are respectively instances of http.IncomingMessage and http.ServerResponse.
The class http.IncomingMessage inherits the end event from the underlying readable stream. The readable stream is not in flowing mode, so the end event never fires, therefore causing the response to never be written. Since the response is already writable when the request handler is run, you can just directly write the response.
var http = require('http');
http.createServer(function(req, res) {
res.writeHead(200, {
'Content-Type': 'text/plain'
});
res.end('Hello HTTP!');
}).listen();

(Javascript) Why doesn't function take parameters

This is a NodeJS stuff, the code is:
var http = require("http");
function onRequest(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}
http.createServer(onRequest).listen(8888);
My question is how come in the last line, the function onRequest doesn't take parameters.. I'm new to Javascript but isn't onRequest supposed to take 2 parameters as defined in the function? Can anyone help me please? I've been stuck for an hour :(
You're not actually calling the method. You're telling createServer what its requestListener callback function is.
From the node.js documentation (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.
Execution of the onRequest function takes 2 parameters.
Your last line:
http.createServer(onRequest).listen(8888);
does not actually execute onRequest, though I can see why you would think it does. It passes a reference to the onRequest function to the http.createServer function / method.
createServer will save a pointer to your onRequest function and then when a request comes into the server, it will execute onRequest. That execution will include a request and response argument.
For details, this article gives a fairly straightforward and concise explanation of this pattern, known as callbacks. It typically goes with asynchronous programming, but doesn't have to.
http://recurial.com/programming/understanding-callback-functions-in-javascript/

Categories

Resources