A few more things we learned about javascript

Hi there! Here’s more Javascript stuff that we found out while doing the coding. Last time we looked at Class.extend – this time though we’ll take a look some stuff the we used on the server-side.

If you are using node.js chances are that your code is littered with callbacks and most functions are broken in the middle more times than you can possibly count – consider for example this function that reads some data from a few files:

 var fs = require('fs'); function readFiles(){ fs.readFile('some_file_with_data', function (err, data) { if (err) throw err; //use some data to read some more data from other files fs.readFile(data,function(err2,data2){ //imagine the need to read more stuff here - this basically just nests and nests and nests..... }); }); } 

Now obviously you might say that we can use the Sync versions of readFile, but that sort of goes against the philosophy of node.js. So what other options have we got to make this code a bit more readable? Well – enter Tame.js.

So now we can rewrite the above code in a more sane way:

 var fs = require('fs'); function readFiles(){ await { fs.readFile('some_file_with_data', defer(var err,data)); } if ( err ) { throw err; } await { fs.readFile(data,defer(var err2,data2)); } // do stuff with data2 } 

Well that looks a bit more logical, doesn’t it – it goes in fact even further – if you have several things that you can do in parallel then put both of them inside the await block. The code after the await block will be executed only when all the variables in the defer statements have been filled.

Now there is one exception to the above sentence – I had to spend several debugging hours to understand it.

Say you have the following code:

 function SomeClass(){ //various constructor code await { lengthyOperation(defer(var _some_data)); } this.data = _some_data; //looks like say { something:1, something_else: 2 } } var inst = new SomeClass(); if ( inst.data.something ) { //do stuff with loaded data } 

You might think that it looks perfectly fine and you expect to reach the part where you can do stuff with the loaded data, right? Well – not gonna happen. Why – well I suppose that’s because Tame in fact does the breaking up of functions behind the scenes and when breaking up the constructor function it returns from it before the end of the await block – this basically means that you shouldn’t use await blocks in constructors unless you are ready for some weird effects. Instead I would recommend writing the above code like this:

 function SomeClass(){ //various constructor code this.init = function() { await { lengthyOperation(defer(var _some_data)); } this.data = _some_data; //looks like say { something:1, something_else: 2 } } } var inst = new SomeClass(); inst.init(); if ( inst.data.something ) { //do stuff with loaded data } 

In this case execution of the init function waits for await block to finish and inst.data.something will be defined as expected.

Leave a Reply

Your email address will not be published. Required fields are marked *