<commit_before>f_
==
Asynchronous Node.js made easier.

### Problem to be solved;
Every (good) Node program is mainly written asynchronously. Ofcourse smaller tasks in larger asynchronous tasks will be synchronous. Some examples are:
* String concatenation
* Simple equation solving
* Variable declaration

And then there are the asynchronous tasks, such as:
* HTTP requests
* Complex equation solving
* Audio/video compressing


When we're looking at the two lists above, we can categorize computational tasks in two separate groups:

1. Synchronous (small and quick)
2. Asynchronous (both small and quick or large and long lasting)

When we are looking at the way Node handles asynchronous computation, we are looking at the simple to grasp and understand yet powerful practice of callbacks. Whilst this practice may be simple, code management and separation of concerns can be diffucult to achieve. This is most likely due to something called 'callback hell'. Which will result in 'christmas tree code'. An example below:

```js
/**
 * Simple task which will first GET google.com source code, write it to a HTML
 * file. When those two tasks are complete it will GET google.nl source code
 * and also write that to a HTML file. Written the most ugly way possible,
 * we're not even using named function declaration above the the async logic.
 */
http.get('http://www.google.com', function (googleRes){
  
  var googleSource = '';
  
  googleRes.on('data', function (googleChunk){
    googleSource = googleSource + googleChunk;
  });
  
  googleRes.on('end', function (){
    fs.writeFile('googleSource.html', googleSource, function (googleWriteErr){
      if(googleWriteErr) return console.log(googleWriteErr);
      
      http.get('http://www.youtube.com', function (ytRes){
        
        var ytSource = '';
        
        ytRes.on('data', function (ytChunk){
          ytSource = ytSource + ytChunk;
        });
        
        ytRes.on('end', function (){
          fs.writeFile('ytSource.html', ytSource, function (ytWriteErr){
            if(ytWriteErr) return console.log(ytWriteErr);
            
            return console.log('Tasks complete!');
          });
        });
      
      });

    });

  });

});
```

As you can see, this code hard to read write and maintain. We're not even taking error handling and dependecy management in account here... Making it even harder to read, write and maintain.


Now let's take a look at the way I want to write this simple task!

```js
/**
 * Please notice we're still not using a good error handling mehtod,
 * the same logic as the ugly example is used.
 * Also note we're not using a class based approach. Just a simple object
 * namespace, since this is a simple demonstration.
 */

var getAndWriteTasks = {};

getAndWriteTasks.getGoogle = function (){
  var self = this;

  http.get('http://www.google.com', function (res){

    var source = '';
    res.on('data', function (chunk){ source = source + chunk; });

    res.on('end', function (){
      // Using the d object namespace to store data we
      // need to use in other/later function scopes
      self.d.googleSource = source;

      // return statement isn't necessary, using it to show we're
      // done with this task.
      return self.next();
    });

  });
};


getAndWriteTasks.writeGoogle = function (){
  var self = this,
      googleSource = self.d.googleSource;

  fs.writeFile('googleSource.html', googleSource, function (err){
    if(err) return console.log(err);
    return self.next();
  });

};

getAndWriteTasks.getYt = function (){
  var self = this;

  http.get('http://www.youtube.com', function (res){

    var source = '';
    res.on('data', function (chunk){ source = source + chunk; });

    res.on('end', function (){
      self.d.ytSource = source;
      return self.next();
    });

  });
};

getAndWriteTasks.writeYt = function (){
  var self = this,
      ytSource = self.d.ytSource;

  fs.writeFile('ytSource.html', ytSource, function (err){
    if(err) return console.log(err);

    // Using next when there are no more tasks will result in a low
    // level f_ API 'f_.finish' method call. Clearing up used memory, etc..
    return self.next();
  });

};
```

Yes, we did it! Separation of concerns. We could even make this modularized to the max. Since all those smaller asynchronous tasks could be single modules, if wanted they can even be put in single files. In this case I would keep it in a single file, since all tasks are small and easy to read/maintain. Even though we are using more lines of code.

So far we can say that `f_` will allow us to program modularized. Which is great already! Well, more greatness is coming your way!

Next up will be error handling. Take a look at a full `f_` example (this time we're using a class based approach, so we can use prototypal inheritance and minimize function creation overhead, getting closer to real world examples!):
```js
```<commit_msg>Small readme fix<commit_after>f_
==
Asynchronous Node.js made easier.

### Problem to be solved;
Every (good) Node program is mainly written asynchronously. Ofcourse smaller tasks in larger asynchronous tasks will be synchronous. Some examples are:
* String concatenation
* Simple equation solving
* Variable declaration

And then there are the asynchronous tasks, such as:
* HTTP requests
* Complex equation solving
* Audio/video compressing


When we're looking at the two lists above, we can categorize computational tasks in two separate groups:

1. Synchronous (small and quick)
2. Asynchronous (both small and quick or large and long lasting)

When we are looking at the way Node handles asynchronous computation, we are looking at the simple to grasp and understand yet powerful practice of callbacks. Whilst this practice may be simple, code management and separation of concerns can be diffucult to achieve. This is most likely due to something called 'callback hell'. Which will result in 'christmas tree code'. An example below:

```js
/**
 * Simple task which will first GET google.com source code, write it to a HTML
 * file. When those two tasks are complete it will GET google.nl source code
 * and also write that to a HTML file. Written the most ugly way possible,
 * we're not even using named function declaration above the the async logic.
 */
http.get('http://www.google.com', function (googleRes){
  
  var googleSource = '';
  
  googleRes.on('data', function (googleChunk){
    googleSource = googleSource + googleChunk;
  });
  
  googleRes.on('end', function (){
    fs.writeFile('googleSource.html', googleSource, function (googleWriteErr){
      if(googleWriteErr) return console.log(googleWriteErr);
      
      http.get('http://www.youtube.com', function (ytRes){
        
        var ytSource = '';
        
        ytRes.on('data', function (ytChunk){
          ytSource = ytSource + ytChunk;
        });
        
        ytRes.on('end', function (){
          fs.writeFile('ytSource.html', ytSource, function (ytWriteErr){
            if(ytWriteErr) return console.log(ytWriteErr);
            
            return console.log('Tasks complete!');
          });
        });
      
      });

    });

  });

});
```

As you can see, this code hard to read write and maintain. We're not even taking error handling and dependecy management in account here... Making it even harder to read, write and maintain.


Now let's take a look at the way I want to write this simple task!

```js
/**
 * Please notice we're still not using a good error handling mehtod,
 * the same logic as the ugly example is used.
 * Also note we're not using a class based approach. Just a simple object
 * namespace, since this is a simple demonstration.
 */

var getAndWriteTasks = {};

getAndWriteTasks.getGoogle = function (){
  var self = this;

  http.get('http://www.google.com', function (res){

    var source = '';
    res.on('data', function (chunk){ source = source + chunk; });

    res.on('end', function (){
      // Using the d object namespace to store data we
      // need to use in other/later function scopes
      self.d.googleSource = source;

      // return statement isn't necessary, using it to show we're
      // done with this task.
      return self.next();
    });

  });
};


getAndWriteTasks.writeGoogle = function (){
  var self = this,
      googleSource = self.d.googleSource;

  fs.writeFile('googleSource.html', googleSource, function (err){
    if(err) return console.log(err);
    return self.next();
  });

};

getAndWriteTasks.getYt = function (){
  var self = this;

  http.get('http://www.youtube.com', function (res){

    var source = '';
    res.on('data', function (chunk){ source = source + chunk; });

    res.on('end', function (){
      self.d.ytSource = source;
      return self.next();
    });

  });
};

getAndWriteTasks.writeYt = function (){
  var self = this,
      ytSource = self.d.ytSource;

  fs.writeFile('ytSource.html', ytSource, function (err){
    if(err) return console.log(err);

    // Using next when there are no more tasks will result in a low
    // level f_ API 'f_.finish' method call. Clearing up used memory, etc..
    return self.next();
  });

};
```

Yes, we did it! Separation of concerns. We could even make this modularized to the max. Since all those smaller asynchronous tasks could be single modules, if wanted they can even be put in single files. In this case I would keep it in a single file, since all tasks are small and easy to read/maintain. Even though we are using more lines of code.

So far we can say that `f_` will allow us to program modularized. Which is great already! Well, more greatness is coming your way!

Next up will be error handling. Take a look at a full `f_` example (this time we're using a class based approach, so we can use prototypal inheritance and minimize function creation overhead, getting closer to real world examples!):
```js

```
{'fraction_non_alphanumeric': 0.09893209752166028, 'fraction_numerical': 0.00040298206729800525, 'mean_word_length': 3.213497453310696, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 8, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1236763', 'n_tokens_mistral': 2777, 'n_tokens_neox': 2656, 'n_words': 1192}