Hai, everyone.
So I just figured out that Connect's static file servers dont work well with symlinks...so I had tow rite myself a little workaround, a fallback router, per-se. But whilst I did so, I had a nice meeting with the callback hell. Here's my code:
<…>
Okay...thats lots. And how does one get around this and into a bit of nicer code? It almost looks like a little pyramid there…
Have you taken a look at Promises? Bluebird is widely considered the fastest implementation. I found Q easier to understand and a bit better documented.
--
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 nodejs+un...@googlegroups.com.
To post to this group, send email to nod...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nodejs/F7E5827B-8287-4C6B-9975-DD0C8CA1059E%40g8o.net.
For more options, visit https://groups.google.com/d/optout.
Promises just wrap callbacks. So you had callback hell, now you have wrapped callback hell. Nice change, huh.
If you want to turn async code to sync-like code, I would suggest to use generators and `co` module instead.
Hai, everyone.
So I just figured out that Connect’s static file servers dont work well with symlinks…so I had tow rite myself a little workaround, a fallback router, per-se. But whilst I did so, I had a nice meeting with the callback hell. Here’s my code:
CDN.use(config.CDN.baseUrl, function(req, res, next){
if(err) { next(); throw err; }
fs.lstat(config.base+"/cdn"+req.url, function(err,stats){
if(stats.isSymbolicLink()) {
fs.readlink(config.base+"/cdn"+req.url, function(err, linkstr){
if(err) throw err;
log.info("Redirecting request \""+req.url+"\" to \""+linkstr);
fs.readFile(linkstr, function(err, data){
if(err) throw err;
res.writeHead(200,{"Content-type":"text/html"});
res.end(data);
});
});
}
});
});
});
Okay…thats lots. And how does one get around this and into a bit of nicer code? It almost looks like a little pyramid there…
On Sep 15, 2014, at 1:01 PM, Alex Kocharin <al...@kocharin.ru> wrote:Promises just wrap callbacks. So you had callback hell, now you have wrapped callback hell. Nice change, huh.Actually yes, I think it is. Readable code is worth it, in my view.
On Sep 15, 2014, at 1:01 PM, Alex Kocharin <al...@kocharin.ru> wrote:Promises just wrap callbacks. So you had callback hell, now you have wrapped callback hell. Nice change, huh.Actually yes, I think it is. Readable code is worth it, in my view.
If you want to turn async code to sync-like code, I would suggest to use generators and `co` module instead.I am waiting for the right time to start recommending generators+X to folks asking these sort of questions. I am not comfortable yet doing so, but I agree that anyone interested should take a look.—ravi
--
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 nodejs+un...@googlegroups.com.
To post to this group, send email to nod...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nodejs/6BCCC31B-7FCD-4B20-A045-7FFAC897A53A%40g8o.net.
CDN.use(config.CDN.baseUrl, function(req, res, next, _) {
var path = config.base + "/cdn" + req.url;
if (fs.lstat(path, _).isSymbolicLink()) path = fs.readlink(path, _);res.writeHead(200, { "Content-type" : "text/html" });res.end( fs.readFile(path, _));});
Hi,
I'm more onto events with EventEmitter() when I need to do a lot of async/sync stuff.
It's built in nodejs, and easy to use out of the box, npm is not required.
Example with sync stuff :
function (data, callback) {
var Events = require("events");
var event = new Events.EventEmitter();
event.on("job1", function (data) {
// do stuff with data
event.emit("job2", err, data);
});
event.on("job2", function (err, data) {
// do stuff with err and data
event.emit("done", err, data);
});
event.on("done", function (err, data) {
// do stuff with err and data
// delete event and remove listeners
callback(err, data);
});
event.emit("job1", data);
}
You get the idea.
For async just call emit after a function is done and keep an array updated so the "done" handle know when all the functions are executed.
Regards.
Edouard Buschini
On Sep 15, 2014, at 10:09 AM, // ravi <ravi-...@g8o.net> wrote:On Sep 15, 2014, at 1:01 PM, Alex Kocharin <al...@kocharin.ru> wrote:Promises just wrap callbacks. So you had callback hell, now you have wrapped callback hell. Nice change, huh.Actually yes, I think it is. Readable code is worth it, in my view.
<snip happens>
Promise.all returns a promise that gives all the values of the promises you pass in. And remember a value without .then can be substituted for a promise -- so you now have an interface that can interpret "later values" and "already available" values identically. That's where the real power comes in: Promises that join and collect results of promises, functions that accept promises (or plain values) and give a promise result.
--
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 nodejs+un...@googlegroups.com.
To post to this group, send email to nod...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nodejs/32603590-e433-43a9-860a-8c12fdbac3f9%40googlegroups.com.
process.on("whatever", function (error, data) {
...
});
I think the async module results in readable code. It's just too verbose to type. (:
To view this discussion on the web visit https://groups.google.com/d/msgid/nodejs/dd788333-b998-4e32-b047-b67ea4add34b%40googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nodejs/16d1698f-8b38-4953-aaa9-5973fc856c78%40googlegroups.com.
How do you implement it with async?
If it didn't have that "if" statement in there it would be a lot simpler - async code doesn't deal well with "if" statements I've found (there's no way to short-circuit
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 nodejs+un...@googlegroups.com.
To post to this group, send email to nod...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nodejs/50de4bdb-7214-412e-a9e2-e844011bccd4%40googlegroups.com.
var baseUrl = config.CDN.baseUrl; CDN.use(baseUrl, checkFileSanity, getRealPath, serveFile); function checkFileSanity (req, res, next) { var filepath = path.join(config.base, '/cdn', req.url); fs.lstat(filepath, function (err, stat) { if(err) return next(err); stat.path = filepath; req.fileStats = stat; next(); }); } function getRealPath(req, res, next) { if(req.fileStats.isSymbolicLink()) { fs.readlink(req.fileStats.path, function (err, realpath) { if(err) return next(err); req.realpath = realpath; next(); }); } else { res.status(404).end(); } } function serveFile (req, res, next) { fs.createReadStream(req.realpath).pipe(res); }
Hai, everyone.
So I just figured out that Connect’s static file servers dont work well with symlinks…so I had tow rite myself a little workaround, a fallback router, per-se. But whilst I did so, I had a nice meeting with the callback hell. Here’s my code:
CDN.use(config.CDN.baseUrl, function(req, res, next){
if(err) { next(); throw err; }
fs.lstat(config.base+"/cdn"+req.url, function(err,stats){
if(stats.isSymbolicLink()) {
fs.readlink(config.base+"/cdn"+req.url, function(err, linkstr){
if(err) throw err;
log.info("Redirecting request \""+req.url+"\" to \""+linkstr);
fs.readFile(linkstr, function(err, data){
if(err) throw err;
res.writeHead(200,{"Content-type":"text/html"});
res.end(data);
});
});
}
Ha-ha, very good example, compare this async version it with the syncversion below, and tell me that there's no problem withcallbacks """if you know how to deal with it""" :DNot saying that in even such a simple code it's extremelyeasy to make small errors like missing `else` statements etc.Also it doesn't preserve the call stack - so when you see error in consoleyou would have no context and no idea what happened...And it still doesn't catch the sync errors...And some of callbacks can be fired twice...And with streams there are lots of events fired and should be properly handled...And still many insist that it is "not a problem".
> I've programmed in both sync and async code, and neither is perfect. Node basically> has trade-offs - I get better performance [1] at the expense of a slightly cumbersome programming model.I compared Node.js with "slow" Ruby on Rails and the result is that node.js is only 1.3 times faster.(maybe there's an error in my benchmark, but I can't find it so far).
> Your sync version doesn't handle errors at allI knew that someone would point to it. But actually it does handle errors. The whole request thread wrapped with try/catch (implicitly, inside of web framework code) - and it does handle errors.
So I would not take this blog article as an authoritative source on exceptions.
CDN.use(config.CDN.baseUrl, function(req, res, next) {
var req_path = config.base+"/cdn"+req.url;
async.waterfall([
fs.lstat.bind(fs, req_path),
function (stats, cb) {
if (!stats.isSymbolicLink()) {
return next();
}
cb(req_path);
},
fs.readlink,
fs.readFile,
function (data) {
res.writeHead(200,{"Content-type":"text/html"});
res.end(data);
}
], next);
});
CDN.use(config.CDN.baseUrl, function(req, res, next, _) {
var path = config.base + "/cdn" + req.url;
if (!fs.lstat(path, _).isSymbolicLink()) {
return next();
}
path = fs.readlink(path, _);
res.writeHead(200, { "Content-type" : "text/html" });
res.end( fs.readFile(path, _));
});
Though, as someone very familiar with the pitfalls of Javascript, and very unfamiliar with streamline, I'd have to look at the generated code to assure myself that's actually doing what I think I want it to, as I could imagine many ways in which that code could be converted to raw asynchronous code incorrectly (I'll assume for now it's smart enough and does it right ; ).