├── .gitignore ├── README.md └── img ├── io.png └── nodejs.png /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # what-is-node 2 | Quick introduction to Node.js 3 | 4 | ## What is Node.js 5 | 6 | * It is a runtime environment that allows you to run Javascript code in the backend (eg on your computer), outside a browser 7 | * The JS is executed by the V8 javascript engine (the thing that makes Google Chrome so fast) 8 | * **Node.js uses an event-driven, non-blocking I/O model** 9 | * Node ships with a lot of useful modules, so you don't have to write everything from scratch 10 | 11 | ## Who is using Node.js? 12 | 13 | Netflix, New York Times, PayPal, LinkedIn, Uber and many more.. 14 | 15 | ## Installation 16 | 17 | If you don’t have the latest version of Node.js installed in your local machine you should do that 18 | now: Head out to [Node.js](https://nodejs.org/en/) and click on the “Install” button. 19 | 20 | ## What are I/O operations? 21 | 22 | I/O stands for input/output 23 | 24 | ![img](https://github.com/heron2014/what-is-node/blob/master/img/io.png) 25 | 26 | Here are some common sources of I/O based programs: 27 | 28 | * Databases (e.g. MySQL, PostgreSQL, MongoDB, Redis, CouchDB) 29 | * APIs (e.g. Twitter, Facebook, Apple Push Notifications) 30 | * HTTP/Web socket connections (from users of a web app) 31 | * Files (e.g image resizer, video editor, internet radio) 32 | 33 | ## What is the event-driven, non-blocking I/O model? 34 | 35 | Node is very good when you need to do several things at the same time. 36 | 37 | Excellent explanation by [art-of-node](https://github.com/maxogden/art-of-node): 38 | 39 | > For example, if you go down to a fast food joint and order a cheeseburger they will immediately take your order and then 40 | make you wait around until the cheeseburger is ready. In the meantime they can take other orders and start cooking cheeseburgers 41 | for other people. Imagine if you had to wait at the register for your cheeseburger, blocking all other people in line from 42 | ordering while they cooked your burger! This is called blocking I/O because all I/O (cooking cheeseburgers) happens one at a time. 43 | Node, on the other hand, is **non-blocking**, which means it can cook many cheeseburgers at once. 44 | 45 | #### Basic example of the non-blocking, asynchronous model 46 | 47 | ``` 48 | setTimeout(function() { 49 | console.log('World'); 50 | }, 2000); 51 | 52 | console.log('2000'); 53 | ``` 54 | 55 | Run this code in [repl.it](https://repl.it/) (or something similar). 56 | 57 | You will see that first output is `2000`, and that the second is `World`. 58 | 59 | `2000` is not 'blocked' by the previous operation, which needs 2 seconds to be completed. Node just gets on executing the next function whilst the first one is still going on. This is **asynchronous**. 60 | 61 | If it *were* a blocking model, there would be a 2-second pause, followed by `World`, and *then* `2000`. That would be *synchronous*. 62 | 63 | #### Conclusion 64 | 65 | When code runs **synchronously**, things happen strictly in order - you wait for it to finish before moving on to another task. 66 | When you execute something **asynchronously**, you can move on to another task before it finishes. 67 | 68 | ## What is a callback - heart of Node.js 69 | 70 | To fully understand how Node.js works you need to know what a callback is. 71 | 72 | A '__callback__' is just a fancy term for a *function that is passed as __an argument to another function__*. 73 | 74 | The point of callbacks is that you pass them into some function that runs asynchronously - it stores your callback away. When that function is done with whatever it needs to do, it will call your callback with the necessary parameters. 75 | 76 | **Example:** 77 | 78 | Imagine we have some operation that runs for a long time, such as fetching some data from the database. And let's say once we have that data, we want to run another function on it. 79 | 80 | ``` 81 | function getStuffFromDatabase() { 82 | // this takes a long time 83 | } 84 | 85 | function doSomethingWithData (dataFromDatabase) { 86 | // some data manipulation happens here 87 | } 88 | 89 | * other code * 90 | ... 91 | ... 92 | ``` 93 | 94 | We don't want our code to run synchronously and block other code from happening, which would waste precious time. 95 | But then our `doSomethingWithData` function mustn't run before the `dataFromDatabase` is ready. 96 | 97 | So how do we make sure our `doSomethingWithData` function runs at the right time, whilst everything is running asynchronously? 98 | 99 | We can re-write `dataFromDatabase` to take a function as an argument. Then when we run `dataFromDatabase`, we can pass in `doSomethingWithData` as its argument. 100 | 101 | In other words, we'll use `doSomethingWithData` as a **callback function**. 102 | 103 | ``` 104 | function getStuffFromDatabase (callback) { 105 | // this takes a long time 106 | 107 | callback(dataFromDatabase); 108 | } 109 | 110 | function doSomethingWithData (dataFromDatabase) { 111 | // some data manipulation happens here 112 | } 113 | 114 | // Let's run the code now. 115 | getStuffFromDatabase(doSomethingWithData); 116 | 117 | * other code * 118 | ``` 119 | Note that the `doSomethingWithData` callback doesn't need invocation brackets - it will still work. 120 | 121 | 122 | Let's test this out in real life. 123 | * We'll simulate taking a long time with a call to ```setTimeout```. 124 | * We'll also pretend we got some data from the database, but we'll just hardcode a string value. 125 | * Then we will console.log the data after the getting-from-database step is finished. 126 | 127 | ``` 128 | function getStuffFromDatabase (callback) { 129 | setTimeout(function() { 130 | var results = "database data"; 131 | }, 5000); 132 | }; 133 | ``` 134 | 135 | Not quite finished: let's make `getStuffFromDatabase` call the callback function, passing to it our database data. 136 | 137 | ``` 138 | function getStuffFromDatabase (callback) { 139 | setTimeout(function() { 140 | var results = "database data"; 141 | callback(results); 142 | }, 5000); 143 | } 144 | ``` 145 | 146 | Now lets run the function with our callback function. 147 | 148 | ``` 149 | function displayData(data) { 150 | console.log(data); 151 | } 152 | 153 | getStuffFromDatabase(displayData); 154 | ``` 155 | 156 | You don't have to declare your callback function separately, by the way. You can also pass it straight in as an anonymous function. The following is *exactly* the same as above: 157 | 158 | ``` 159 | getStuffFromDatabase(function(data) { 160 | console.log("The database data is " + data); 161 | }); 162 | ``` 163 | 164 | So, as you can see ```data``` came from the function that you pass your callback into; 165 | it gives that data to you when it knows what that data should be. 166 | 167 | 168 | 169 | 170 | Look at this example. This **won't** work how we want it to: 171 | 172 | ``` 173 | // executed immediately executed sometime in the future by getStuffFromDatabase 174 | // | | 175 | // v v 176 | getStuffFromDatabase(function(data) { 177 | var results = data; // <- this isn't available until sometime in the future! 178 | }); 179 | 180 | console.log(results); // <- executed immediately 181 | ``` 182 | 183 | When the ```console.log``` runs we will get `undefined`. Because of Node's non-blocking model, it will not wait for `getStuffFromDatabase` to complete - it will just move straight on to the next task. 184 | 185 | When Node reaches the `console.log`, the assignment of ```var results``` hasn't happened yet! 186 | 187 | So the reason you can't set a value in your callback and use it outside the callback is because the **callback itself doesn't happen 188 | until later in time**. 189 | 190 | ### Conclusion 191 | 192 | That's exactly how Node.js works, it requires you to **think non-linearly**. This means that you can fire off several async calls 193 | to retrieve files, fetch data (or any event which takes time to complete) and **not lock the main thread** while it renders the content. 194 | 195 | **The power of async** is being able to do **multiple things at the same time** without locking the main thread. 196 | 197 | ## How Node.js works under the hood 198 | 199 | Node.js platform uses a **“Single Threaded Model with Event Loop”** architecture to handle multiple concurrent clients. 200 | 201 | 202 | 1. Client sends request to web server 203 | 2. Node.js web server receives those requests and places them into a **queue – known as a “event queue”**. 204 | 3. Node.js has a component internally, known as a the **“Event Loop”** - which picks up those requests one by one. 205 | 4. Event Loop uses a **single thread** only – which is a heart of Node.js model. 206 | **Single Thread means that the program can run one piece of code at a time**. 207 | 208 | The event loop's job is: 209 | 210 | * to check whether a client request needs blocking I/O operations (like interacting with a database, file system or external API ) 211 | or non-blocking I/O task 212 | * if a request is **non-blocking task**, it prepare response and send it back to the client 213 | * if a request is a **blocking I/O operation**, the event loop does not process this request. Instead it picks up one thread 214 | from the internal **thread pool** and assigns this client request to it. In this way the event loop can serve other clients 215 | without locking the main thread. 216 | * This thread is responsible for taking that request, processing it, preparing the response and sending it back to the event loop 217 | * The event loop, in turn, sends this response back to the client 218 | 219 | 220 | ![img](https://github.com/heron2014/what-is-node/blob/master/img/nodejs.png) 221 | 222 | 223 | To understand more about the single-threaded versus multi-threaded model please refer [here](http://www.journaldev.com/7462/node-js-processing-model-single-threaded-model-with-event-loop-architecture) 224 | 225 | ## Why Javascript? 226 | 227 | Ryan Dahl (creator of Node.js), wants a completely asynchronous net server 228 | 229 | * Ruby VM was slow... 230 | * C/C++ is too complicated 231 | * Lua is perfect except its I/O libraries were only synchronous 232 | * Enter JavaScript: 233 | * A naturally single-threaded/event-driven model, asynchronisation 234 | * almost blank area on the server side, so no issues of breaking old habits 235 | 236 | 237 | ## How do I start 238 | 239 | Follow our next tutorial [here](https://github.com/node-girls/learn-node) 240 | 241 | ## Resources 242 | 243 | * [NodeSchool.io interactive lessons](http://nodeschool.io/) 244 | * [Node.js guide](http://nodeguide.com/) 245 | * [The Art of Node (an introduction to Node)](https://github.com/maxogden/art-of-node/#the-art-of-node) 246 | * [Absolute Beginners Guide To Node.js](http://blog.modulus.io/absolute-beginners-guide-to-nodejs) 247 | * [Learn Node.js Completely and with Confidence](http://javascriptissexy.com/learn-node-js-completely-and-with-confidence/) 248 | * [Excellent article by Felix Geisendörfer](http://debuggable.com/posts/understanding-node-js:4bd98440-45e4-4a9a-8ef7-0f7ecbdd56cb) 249 | * [Great explanation of the event loop](https://www.youtube.com/watch?v=8aGhZQkoFbQ) 250 | * [All other resources listed nicely here](http://stackoverflow.com/questions/2353818/how-do-i-get-started-with-node-js) 251 | -------------------------------------------------------------------------------- /img/io.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heron2014/what-is-node/d9a7ad9d2d63882ebcc148c6bcbafbc0c2a2ecd2/img/io.png -------------------------------------------------------------------------------- /img/nodejs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heron2014/what-is-node/d9a7ad9d2d63882ebcc148c6bcbafbc0c2a2ecd2/img/nodejs.png --------------------------------------------------------------------------------