So, a few problems:
- BLOCKING!
That's your main issue. Your while() loop with dates is blocking your
entire app server. It's not like say, PHP where each request gets its own
instance of a PHP script. Here, one app, one script handles all requests.
So when you block with while loop, you block all requests and that's why
your second request is delayed. It's actually executed immediately, but
immediately after it's been received. Which is after all those milions of
while loop spins.
That's a very bad practice. You'll also probably notice that your CPU is at
100% during your long requests.
How to remedy it? Use setTimeout.
So, your userRepository would do something like this:
getUsers: function(long, callback) {
if(!long) {
db.users.find({}, function(err, usersList) {
callback(err, usersList);
});
} else {
setTimeout(function() {
db.users.find({}, function(err, usersList) {
callback(err, usersList);
});
}, 5000);
}
}
Your second issue is method signature, like somebody has mentioned already.
Your callbacks will usually be the LAST parameter to the request handlers.
Also, in the callback, you will usually pass err or null as the first
argument. Say that your db is down - you will want to pass that info and
your render('index') might look like render('db-error'); instead.
On Wednesday, August 20, 2014 3:26:14 PM UTC+2, Дмитрий Папка wrote:
>
> Hello, everyone!
> I am new to Node.Js and not very well understanding the mecanics of
> callbacks.
>
> I have a MongoDB database installed and running. I have a 'users'
> collection. In my Node.js (Express) application I want to display a list of
> stored users.
> I am doing the following experiment:
>
> var express = require('express');
> var router = express.Router();
> var userRepository = require('../repositories/user_repository.js');
>
> router.get('/:long?', function(req, res) {
> var long = req.param('long');
> long = !!long;
> userRepository.getAllUsers(function(users) {
> res.render('index', {
> users: users
> });
> }, long);
> });
>
> It's a handler for my http://website.com/ URL, which may have an optional
> URL parameter 'long' I am passing it to my userRepository.getAllUsers
> method.
>
> userRepository looks like this:
>
> var db = require('../context').db;
>
> var userRepository = {
> getAllUsers: function(callback, long) {
> var now = Date.now();
> var then = now + 5000;
> if (long) {
> while (Date.now() < then) {}
> }
> db.users.find({}, function(err, users) {
> callback(users);
> });
> }
> };
>
> module.exports = userRepository;
>
> context.js contains only mongoDB settings (username, password, url).
>
> The idea is the following:
>
> If user enters url: http://website.com/, then 'long' parameter will be
> false and userRepository will just get user list from database and will
> render to my view.
>
> If user enters url: http://website.com/?long=something, then 'long'
> parameter will be true and before extracting user list, getAllUsers will
> 'sleep' for 5 seconds.
>
> With this approach I am trying to simulate a long-time operation (for
> example, if my users colletion has a lot of documents and we are trying to
> get them all).
>
> If I am openning: *http://website.com/ <http://website.com/>*, it loads
> immediately.
> If I am oppening: *http://website.com/?long=something
> <http://website.com/?long=something>*, it loads after ~ 5 seconds as
> expected.
> Now. If I am openning *http://website.com/?long=something
> <http://website.com/?long=something>* and right after *that
> **http://website.com/
> <http://website.com/> - *they both are loading 5 seconds (second request
> is waiting until the first one will end).
> That means I am doing something wrong, because requests are handled not
> asyncroniously.
> What did I do wrong?
>
--
Job board: http://jobs.nodejs.org/
New group rules:
https://gist.github.com/othiym23/9886289#file-moderation-policy-md
Old group rules:
https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
---
You received this message because you are subscribed to the Google Groups
"nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/nodejs/205b8c08-6da4-4ace-98a0-51e5fb97c718%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.