Skip to content
jodoglevy edited this page Sep 18, 2011 · 6 revisions

Spacing

We shall be using 4-space wide tabs (rather than 2-space). On top of that, configure your text-editor to use 4 spaces instead of a "\t" character (when you hit the Tab key that is).

For Gedit (Joe): http://cs.smu.ca/~myoung/csci1227/UsingNXWindows.html#Tabs

For Vim: set tabstop=4; set softtabstop=4; set shiftwidth=4; set autoindent; set smartindent;

Asynchronous Programming

Basics

Asynchrounous programming is a completely different paradigm from synchronous programming. Unlike before, we have to consider race conditions in which variables are used before they are assigned, which would result in null pointer exceptions.

In managed code, it is common to see methods such as "BeginInitialize()" or "EndConnect()", usually indicating that such methods are asynchronous, and would fall right through when called. As nodeJS is a functional programming language built to be asynchronous, nearly all of the functions we call, will be, well... asynchronous.

There are several methods to indicate whether a method call is synchronous or asynchronous. Naming conventions in our case would be rather ridiculous, since most methods are async. Thus, we shall leave it to the developer to enforce the async nature of the method by forcing a callback to be passed in, as will be described in the next section.

Javascript is an interesting language - unlike C#, C++, or Java, which are strong typed languages, there is no type checking in JS, making it weak typed.

This also means that functions are inherently "overloaded", and you can call a function with any number of arguments up to the actual declaration of the function.

Example:

function foo(arg1, arg2, arg3, arg4, arg5){
    ... Some implementation ...
}

foo("hi");  // Works
foo("hi", "joe", "is", "noob"); // Works
foo("joe","wants","braces","like","brian"); // Works
foo("joe","is","dean's","bitch","what","a","noob"); // Compile Errors.

We shall exploit this ability to deal with async callbacks.

Method Parameters

If a method has ANY asynchronous call that has an effect on the state of a program, or a method that has be to be prior to others (e.g an Initialize() function)), you MUST insert a callback parameter as the last argument to the function.

Example:

api.getArticles= function(parent_node, count, callback) {
    var start = [parent_node];
    var end = [parent_node, {}];
    db.view("articles/descendants", {
        startkey: start,
        endkey: end,
        limit: count
    },
    callback);
};

Stylistic Considerations

Too often we see the following verbose code:

function(err, result){
    if(err)
        callback(err);
    else
    {
        ...
    }
}

or the more errorneous:

function(err, result){
    if(err)
        callback(err);
    ...

}

Instead, consider:

function(err,result){
    if(err)
        return callback(err);
    
    ...
}

The first example is rather wordy, the else statement shouldn't be needed. The 2nd example is unacceptable, as the code after the error check will still run.

The 3rd example is not only less wordy, it also prevents code from running when it isn't supposed to.

As good coding practice, we can exploit the fact that JS allows one to return anything, including 'null'. Thus, before every "callback()" call, insert a "return" keyword to indicate the end of a branch for easier reading.

Do not mix Async / Sync paradigms

If you're writing an asynchronous method, do not use synchronous patterns, as that would usually lead to disaster. For one, asynchronous methods should NOT use the "return" keyword to return a value. Synchronous method have headers like (strong typing for clarity):

object SyncMethod(object[] params, ...)
{
    ...
    return (object) value;
}

On the other hand, ALL asynchronous methods should have headers similar to the following structure (strong typing for clarity):

void AsyncMethod(object arg1, object arg2, ... , (void*) callbackHandler(object c1, object c2, ...);

Note that the AsyncMethod should ALWAYS be void. All state changes should be encapsulated within the callback result. Anything else would be ugly/confusing async programming.

Methods meant to be private to a file should begin with "_"

If you are writing a function only meant to be used internally by the file's public functions, put a '_' onto the front of it so people know not to use it external to the file

function _myPrivateFunction() {
    ....
}

Clone this wiki locally