I have a node process running that do some unirest.get and unirest.post from time to time. I also have a type of web terminal from which I can see the overall progress of said unirest requests.
The problem is that I need to be able to cancel a specific request, but I can't find out how.
The structure is something like this:
var requests = [];
requests.push(unirest.post('someurl').end(somecallback));
requests.push(unirest.post('someurl').end(somecallback));
requests.push(unirest.post('someurl').end(somecallback));
And I want to do something like:
requests[1].cancel(); // but of course this method doesn't exist
since in this case I can't let the callback fires, since the goal is to cancel it to request the same url again, and without canceling it the callback would fire twice.
Anyone knows how to cancel/interrupt/destroy it?
Result of unirest.post('someurl').end(some callback) is Request object from request module.
So, you can use abort method:
requests[1].abort();
Related
So I've got a working node.js code that processes data from a website's API. I'd like to speed it up a bit and I figured the best way to do that would be to send a request and while waiting for a response some code would execute and not just wait for a response like it is now. Right now my code is essentially this:
function httpGet(url){
var response = requestSync(
'GET',
url
);
return response.body;
}
var returnCode;
var getUrl = "url"
returnCode = httpGet(getUrl);
var object = JSON.parse(returnCode);
//Some code executes
As you can see with this way some time is lost because you're waiting for the response. I'd be looking for something in this sense (pseudocode):
Send a request
Some code that's not related to the request is executed right after the request is sent
After the part above is done the request result is parsed
In conclusion I'm looking for a way to send a request and not waste time waiting for a response. If you have any other ideas on how to speed up the code please let me know :)
You are looking for asynchronous code. When you use a function like requestSync it means that it "blocks" until it's done. It's synchronous. When you use something asynchronous, you will usually do so with a callback (a function to call when the desired action is completed) or a promise (an abstraction over callbacks). There are lots of questions about using those on SO. This post: How do I return the response from an asynchronous call? has a bunch of info related to your question.
I wonder how to access req object if there's no 'req' parameter in callback.
This is the scenarioļ¼
In ExpressJs, I have a common function, it uses to handle something with 'req' object, but not pass req into it.
module.exports = {
get: function(){
var req = global.currentRequest;
//do something...
}
}
My current solution is that I write a middleware for all request, I put the 'req' in global variable, then I can access the 'req' everywhere with 'global.currentRequest'.
// in app.js
app.use(function (req, res, next) {
global.currentRequest= req;
next();
});
But I don't know if it's good? Can anyone have suggestions?
Thanks a lot!
The only proper way is to pass the req object through as an argument to all functions that need it.
Stashing it in a global simply will not work because multiple requests can be in process at the same time if any requests use async calls as part of their processing and those multiple requests will stomp on each other making a hard to track down bug. There are no shortcuts here. Pass the current request as an argument to any code that needs it.
You cannot put request-specific data into a global in node.js, ever. Doing so will create an opportunity for two requests that are in-flight at the same time to stomp on each other and for data to get confused between requests. Remember, this is a server that is potentially handling requests for many clients. You cannot use synchronous, one-at-a-time thinking for a server. A node.js server may potentially have many requests all in flight at the same time and thus plain globals cannot be used for request-specific data.
There is no shortcut here. You will just have to pass the req object through to the function that needs it. If that means you have to change the function signature of several intervening functions, then so-be-it. That's what you have to do. That is the only correct way to solve this type of problem.
There are some circumstances where you may be able to use a closure to "capture" the desired req object and then use it in inner functions without passing it to those inner functions, but it does not sound like that is your function structure. We'd have to see a lot more of your real/actual code to be able to know whether that's a possibility or not.
Actually, this is possible with something like global-request-context
This is using zone.js which let you persist variables across async tasks.
I don't know much about how the https module in node.js works so if any of you can answer this question then that would be great.
I have noticed in a small app I made that it takes about ~150ms for a HTTPS.get(...) function to execute from scratch before any actual request is sent out. This is what im talking about:
var http = require('http');
var https = require('https');
console.time("Begin");
function request() {
console.timeEnd("Begin");
var myvar = https.get("https://www.fiadkbjadfklblnfthiswebsidedoesnotexist.com", function(res) {
});
console.timeEnd("Begin");
}
request();
When I use 'https.get', the console says that approximately 150ms passed before the code even starts doing anything with the get request. However when I use 'http.get' the delay is less than <5ms.
My question is, what exactly is causing this 150ms delay and is there anyway to reduce it? Im sure that it is not ssl handshaking because this delay happens even when I input a non-existant website. It would be great if it was possible to code something earlier in the program so that when I execute a https.get() request, it would not have such a long startup time.
You are using console.timeEnd('Begin') multiple times in your code
As of node v6.0.0, timeEnd() deletes the timer to avoid leaking it
So when you call console.timeEnd('Begin') first, it deletes the timer & on second call of console.timeEnd('Begin') it can not find the reference to same
You can create multiple labels if you want 2 timers for different issues, but make sure you just write timeEnd() only once for every time()
In my index.js, I have an exports function that is supposed to send data back to the client via ajax on pressing a submit button. However, when the user presses submit, the data seems to get sent over before it the data gets modified. When pressing submit one more time, it sends the data that was previously modified as if clicking the submit button only sends the 'previously' set data. This is my code:
var tabledata = getRecordFromDatabase(key);
if(tabledata.length === 0)
tabledata = 'There is no matched record in the database';
res.contentType('text/html');
res.send({'matched':tabledata});
So to illustrate the error: I click submit after filling out a form and receive back the message "There is no matched record in the database". I hit submit a second time without changing anything in the form I just filled. This time record data is actually sent to me. Why could this be?
If whatever you're doing in getRecordFromDatabase is asynchronous and non-blocking, then node.js is behaving as it should. Node.js is non-blocking - it doesn't stop and wait for processes to complete (unless those processes are intentionally written to block, which is usually avoided in node.js). This is beneficial, because it keeps the server free to accept new requests and process many requests at once.
If your database call is asynchronous, you're not waiting for it to return before you res.send(). That's why your first submit returns back empty. Most likely, by the time you hit submit a second time, your DB call has finally returned, and that's why you get a result.
It's hard to give you a code-based answer to your problem, because you abstracted away what is happening in your DB call method. But typically, an asynchronous call would go something like:
getRecordFromDatabase(key, function(err, data){
if(data.length === 0)
data = 'There is no matched record in the database';
res.contentType('text/html');
res.send({'matched':data});
});
This way, you are passing a function to execute as a callback to your asynchronous method - when the async call completes, it executes the callback, which then executes the res.send() with the appropriate data.
In express you call var app = module.exports = express.createServer(); which creates a new HTTPServer object. I'd like to get access to the current req object from this app(HTTPServer) object. Is there a way to do this?
The req object is only created when the underlying HTTPServer actually gets a request, and only lasts for as long as the request is processed. So it's not really meaningful to talk about it outside the context of a callback.
During a callback, you can simply copy the appropriate data from the session object somewhere else and use that copy in your websockets code. But you can't count on the request object, or even the session object, remaining after you've finished processing the request.
Showing a small code example would be helpful; it sounds like you've got an "XY problem" (you want to accomplish a goal X and you've decided that technique Y is the right way to do it, when in fact technique Z might work better).