Luciano Mammino PRO
Cloud developer, entrepreneur, fighter, butterfly maker! #nodejs #javascript - Author of https://www.nodejsdesignpatterns.com , Founder of https://fullstackbulletin.com
Luciano Mammino (@loige)
June 24, 2020
University Webinar Series
Principal Software Engineer at FabFitFun
👨🏻🏫 Mentor and co-organizer at NodeSchool Dublin
JavaScript is an high-level, interpreted, multi-paradigm, dynamic & loosely-typed programming language
High-level: the language abstracts many system details (e.g. memory management).
Focus on productivity rather than control.
int *array = malloc(10 * sizeof(int));
if (array == NULL) {
fprintf(stderr, "malloc failed\n");
return -1;
}
// ...
free(array);
var arr = []
C (low-level)
JavaScript (high-level)
Interpreted: the source code can be executed directly using an interpreter (there is no compilation step).
Focus on portability and productivity rather than performance
javac HelloWorld.java
java HelloWorld.class
node hello-world.js
Java (compile)
JavaScript (intepreted)
Multi-paradigm: the language supports multiple programming paradigms:
Focus on flexibility and freedom rather than consistency
dynamic: the type of variables does not need to be defined.
loosely typed: the type of variables can change over time and different types of variables can be combined (through auto-casting)
Focus on productivity rather than safety.
a = "Hello"
a = 2
b = "Hello" + 2 # TypeError!
var a = "Hello"
a = 2
var b = 'Hello' + 2 // 'Hello2'
python (dynamic, strongly typed)
JavaScript (dynamic, loosely typed)
Brendan Eich
(in a suit!)
In the last two decades, JavaScript has effectively revolutionized the web, eventually becoming the standard "de facto" for building dynamic websites and web applications!
Async I/O
In JavaScript, input/output operations (e.g. making an HTTP request) are non-blocking.
Most languages have blocking I/O by default
Let's make an HTTP request in Java
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://google.com")
.build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
System.out.println("Request completed");
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://google.com")
.build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
System.out.println("Request completed");
.
Output
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://google.com")
.build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
System.out.println("Request completed");
.
Output
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://google.com")
.build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
System.out.println("Request completed");
.
Output
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://google.com")
.build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
System.out.println("Request completed");
.
Output
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://google.com")
.build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
System.out.println("Request completed");
.
Output
(Blocking I/O)
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://google.com")
.build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
System.out.println("Request completed");
<google home page HTML code>
Output
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://google.com")
.build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
System.out.println("Request completed");
<google home page HTML code>
Request completed
Output
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://google.com")
.build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
System.out.println("Request completed");
<google home page HTML code>
Request completed
Output
Code executed
"in order"
Is blocking I/O bad?
Is blocking I/O bad?
(it depends...)
Is your application I/O heavy?
Is your application I/O heavy?
If yes, then blocking I/O might not be optimal!
If you have to do 3 requests...
If you have to do 3 requests...
Req 1
time
If you have to do 3 requests...
Req 1
time
If you have to do 3 requests...
Req 1
time
Req 2
If you have to do 3 requests...
Req 1
time
Req 2
If you have to do 3 requests...
Req 1
time
Req 2
Req 3
If you have to do 3 requests...
Req 1
time
Req 2
Req 3
You can always use threads...
thread 1
time
thread 2
thread 3
You can always use threads...
thread 1
time
thread 2
thread 3
You can always use threads...
thread 1
time
thread 2
thread 3
But threads are...
You can always use threads...
thread 1
time
thread 2
thread 3
But threads are...
Complicated
You can always use threads...
thread 1
time
thread 2
thread 3
But threads are...
Complicated
Expensive
You can always use threads...
thread 1
time
thread 2
thread 3
But threads are...
Complicated
Expensive
Still a lot of idle time per thread!
You can always use threads...
thread 1
time
thread 2
thread 3
idle time
idle time
idle time
But threads are...
Complicated
Expensive
Still a lot of idle time per thread!
Let's understand JavaScript async I/O with a similar example...
request.get('https://google.com').end(
(err, resp) => {
console.log(resp.text)
}
)
console.log('Request completed (?)')
request.get('https://google.com').end(
(err, resp) => {
console.log(resp.text)
}
)
console.log('Request completed (?)')
.
Output
request.get('https://google.com').end(
(err, resp) => {
console.log(resp.text)
}
)
console.log('Request completed (?)')
.
Output
request.get('https://google.com').end(
(err, resp) => {
console.log(resp.text)
}
)
console.log('Request completed (?)')
.
Output
request "in the background"
request.get('https://google.com').end(
(err, resp) => {
console.log(resp.text)
}
)
console.log('Request completed (?)')
Request completed (?)
Output
request "in the background"
not blocking,
execution continues...
request.get('https://google.com').end(
(err, resp) => {
console.log(resp.text)
}
)
console.log('Request completed (?)')
Request completed (?)
Output
request "in the background"
not really completed, still in progress!
request.get('https://google.com').end(
(err, resp) => {
console.log(resp.text)
}
)
console.log('Request completed (?)')
Request completed (?)
Output
request completed ⏰
request.get('https://google.com').end(
(err, resp) => {
console.log(resp.text)
}
)
console.log('Request completed (?)')
Request completed (?)
Output
request completed ⏰
Callback function
request.get('https://google.com').end(
(err, resp) => {
console.log(resp.text)
}
)
console.log('Request completed (?)')
Request completed (?)
<google home page HTML code>
Output
request.get('https://google.com').end(
(err, resp) => {
console.log(resp.text)
}
)
console.log('Request completed (?)')
Request completed (?)
<google home page HTML code>
Output
request.get('https://google.com').end(
(err, resp) => {
console.log(resp.text)
}
)
console.log('Request completed (?)')
Request completed (?)
<google home page HTML code>
Output
⚠️ Code NOT executed "in order"
request.get('https://google.com').end(
(err, resp) => {
console.log(resp.text)
}
)
console.log('Request completed (?)')
Request completed (?)
<google home page HTML code>
Output
⚠️ Code NOT executed "in order"
①
request.get('https://google.com').end(
(err, resp) => {
console.log(resp.text)
}
)
console.log('Request completed (?)')
Request completed (?)
<google home page HTML code>
Output
⚠️ Code NOT executed "in order"
①
②
request.get('https://google.com').end(
(err, resp) => {
console.log(resp.text)
}
)
console.log('Request completed (?)')
Request completed (?)
<google home page HTML code>
Output
⚠️ Code NOT executed "in order"
①
②
③
When is this approach convenient?
When is this approach convenient?
For I/O heavy applications
When is this approach convenient?
For I/O heavy applications
JavaScript was built for the Browser, which is I/O heavy!
But why?
But why?
You just have to schedule async I/O and you will get notified when the operation is completed!
But why?
You just have to schedule async I/O and you will get notified when the operation is completed!
No explicit thread creation!
In fact, the "user" code runs in a single thread!
How?
How?
Thanks to the event loop!
How?
Thanks to the event loop!
It executes I/O efficiently in the background
If you have to do 3 requests...
If you have to do 3 requests...
"user" thread
time
Event loop
If you have to do 3 requests...
"user" thread
time
Sched. req 1
Event loop
If you have to do 3 requests...
"user" thread
time
Sched. req 1
Event loop
If you have to do 3 requests...
"user" thread
time
Event loop
Sched. req 2
If you have to do 3 requests...
"user" thread
time
Event loop
Sched. req 2
If you have to do 3 requests...
"user" thread
time
Event loop
Sched. req 3
If you have to do 3 requests...
"user" thread
time
Event loop
Sched. req 3
If you have to do 3 requests...
"user" thread
time
Event loop
idle
If you have to do 3 requests...
"user" thread
time
Event loop
idle
req 1 result
If you have to do 3 requests...
"user" thread
time
Event loop
idle
If you have to do 3 requests...
"user" thread
time
Event loop
idle
idle
If you have to do 3 requests...
"user" thread
time
Event loop
idle
idle
req 3 result
If you have to do 3 requests...
"user" thread
time
Event loop
idle
idle
If you have to do 3 requests...
"user" thread
time
Event loop
idle
idle
idle
If you have to do 3 requests...
"user" thread
time
Event loop
idle
idle
idle
req 2 result
If you have to do 3 requests...
"user" thread
time
Event loop
idle
idle
idle
If you have to do 3 requests...
"user" thread
time
Event loop
idle
idle
idle
Simpler code for the user
If you have to do 3 requests...
"user" thread
time
Event loop
idle
idle
idle
Simpler code for the user
idle time only in one thread
This was a gross simplification...
Watch loige.link/event-loop-what-the-heck
if you want to go more in depth!
Since async is so fundamental there are many abstractions to handle async flow:
Ecosystem
Universal / Isomorphic web development
If you use JavaScript & Node.js you can build full stack web applications (frontend + backend) using only one language!
Bonus:
Javascript is one of the fastest scripting languages
Some resources:
⚠️ WARNING
JavaScript is a pragmatic and beautiful language, but like everything, it's far from perfect and it has many quirks...
JavaScript WAT, a short talk by Gary Bernhardt
loige.link/js-wat
Node.js is an open-source, cross-platform, JavaScript runtime environment that executes JavaScript code outside a web browser.
Created and launched in 2009 by Ryan Dahl to have a way to run JavaScript code outside a browser.
npm was launched in the same year.
Big companies (Linkedin, Uber, Paypal, Walmart) adopt Node.js early on.
In 2015 the Node.js foundation (now OpenJS) is born. (1)
Ryan Dahl
(in a T-shirt!)
Thanks to @gbinside, @StefanoAbalsamo, @PadraigOBrien, @mariocasciaro & @hernandezlobera
for reviews and feedback!
By Luciano Mammino
In this talk, we will discuss JavaScript. Why does JavaScript exist in the first place? What is it useful for? How is it different from other mainstream languages like Java, Python or C? When you should consider using JavaScript (and when you shouldn't). We will also explore JavaScript server-side: Node.js and finally we will discuss when to use JavaScript + Node.js and when not to!
Cloud developer, entrepreneur, fighter, butterfly maker! #nodejs #javascript - Author of https://www.nodejsdesignpatterns.com , Founder of https://fullstackbulletin.com