-
Notifications
You must be signed in to change notification settings - Fork 1
/
lecture1.html
834 lines (745 loc) · 26.2 KB
/
lecture1.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
<!DOCTYPE html>
<!--
Web 2.0, CTU course slides
(cc) 2010-2013 Tomas Vitvar, tomas@vitvar.com
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="course" content="Web 2.0" />
<meta name="lecture" content="Lecture 1" />
<meta name="keywords" content="javascript, arrow function, promise, nodejs, event loop, blocking i/o" />
<link type="text/css" rel="stylesheet" href="css/meta.css">
</link>
<link type="text/css" rel="stylesheet" href="css/ctu-fit.css">
</link>
<link type="text/css" rel="stylesheet" href="humla/lib/core/humla.css">
</link>
<script type="text/javascript" src="humla/lib/humla.js"></script>
<title>Asynchronous I/O</title>
</head>
<body>
<footer>
<p><b>#META_LECTURE#: #TITLE#</b>, <span class="meta_semester" />,
<span class="meta_twitter" />
</p>
<p><b>‒ #SLIDE_NO# ‒</b></p>
</footer>
<div class="slide intro">
<hgroup>
<h1><span class="meta_course" /></h1>
<h2>#META_LECTURE#: #TITLE#</h2>
</hgroup>
<div class="author">
<p class="meta_author" />
<p><span class="meta_email" /> • <span class="meta_twitter" /> •
<span class="meta_web" />
</p>
</div>
<center>
<div class="meta_logo"></div>
</center>
<div class="org">
<p class="meta_org" />
<p><span class="meta_orgfac" /> • <span class="meta_field" />
• <span class="meta_orgweb" /></p>
</div>
<div class="etc">
<div class="text-info">
Modified: #LAST_MODIFIED#<br />
Humla v#HUMLA_VERSION#
</div>
<a href="http://creativecommons.org/licenses/by-sa/3.0/">
<div class="license"></div>
</a>
<div class="oppa"></div>
</div>
</div>
<div class="slide outline"></div>
<section>
<header>Asynchronous I/O Overview</header>
<div class="slide">
<hgroup>
<h1>Recall: Application Server</h1>
</hgroup>
<ul class="small">
<li>Environment that runs an application logic</li>
<ul>
<li>Client communicates with AS via an application protocol</li>
<li>Client – Browser, application protocol – HTTP</li>
</ul>
<li>Terminology</li>
<ul>
<li>Application Server × Web Server × HTTP Server</li>
<ul>
<li>AS is a modular environment; provides technology to realize enterprise systems</li>
<li>AS contains a Web server/HTTP server</li>
</ul>
<li>We will deal with Web server only</li>
</ul>
<li>Two major models to realize communication</li>
<ul>
<li>Blocking I/O (also called synchronous I/O)</li>
<li>Non-blocking I/O (also called asynchronous I/O)</li>
</ul>
<li>A technology we will work with</li>
<ul>
<li>Node.js – runs server-side Javascript</li>
</ul>
</ul>
</div>
<div class="slide">
<hgroup>
<h1>Programming Models</h1>
</hgroup>
<ul class="small">
<li>Concurrency</li>
<ul>
<li>Multiple tasks have the ability to run in an overlapping manner</li>
<li>Concurrency does not imply parallelism!</li>
</ul>
<li>Multiprocessing</li>
<ul>
<li>CPU-bounded tasks</li>
<li>Allows to process multiple processes on different CPUs</li>
</ul>
<li>Multithreading</li>
<ul>
<li>I/O bound tasks</li>
<li>Multiple threads execute tasks</li>
<li>A process may contain multiple threads</li>
<li>It uses <b>preemtive multitasking</b></li>
<ul>
<li>OS decides how long a task should run (no tasks cooperation)</li>
<li>context switching</li>
</ul>
<li>Threads can access shared memory; you need to controll this</li>
</ul>
</ul>
</div>
<div class="slide">
<hgroup>
<h1>Asynchronous I/O</h1>
</hgroup>
<ul class="small">
<li>Asynchronous I/O</li>
<ul>
<li>A style of concurrent programming; it is not a parellelism</li>
<li>Single-threaded, single process design</li>
<li>It uses <b>cooperative multitasking</b></li>
</ul>
<li>Asynchronous processing of a task</li>
<ul>
<li>Tasks are running in so called <b>event loop</b></li>
<li>A task is able to "pause" when they wait for some result</li>
<ul>
<li>A task let other tasks to run</li>
</ul>
<li>Asynchronous code faciliates concurrent execution</li>
<ul>
<li>It gives the "look and feel" of concurrent execution</li>
</ul>
</ul>
</div>
</section>
<div class="slide outline"></div>
<section>
<header>Asynchronous I/O in JavaScript</header>
<div class="slide">
<hgroup>
<h1>Web 2.0 Application Architecture</h1>
</hgroup>
<div id="1MXZwvAJA_NKdUnVm-1DNBtgFdCsoYSNIjkfaP2Q4TlY" class="h-drawing"
style="height: 470px; margin-top: 20px"></div>
</div>
<div class="slide">
<hgroup>
<h1>JavaScript</h1>
</hgroup>
<ul class="x-small">
<li>Lightweight, interpreted, object-oriented language</li>
<li>Client-side (browser) and server-side (node.js, AppsScript)</li>
<li>Standard</li>
<ul>
<li>Current stable release is ECMAScript 2021/June 2021</li>
</ul>
<li>Major characteristics</li>
<ul>
<li>Function is an Object</li>
<ul>
<li>passing functions as arguments to other functions</li>
<li>returning functions as values from other functions</li>
<li>assigning functions to variables</li>
<li>storing functions in data structures.</li>
</ul>
<li>Anonymous functions</li>
<ul>
<li>declared without any named identifier to refer to it</li>
</ul>
<li>Arrow functions</li>
<li>Closures</li>
</ul>
</div>
<div class="slide">
<hgroup>
<h1>Javascript Runtime</h1>
</hgroup>
<div id="1kfGhsbXThWPmWqMx6-Y8UkBUlgoaCbiJCFQ7qIIcddQ" format="png" class="h-drawing"
style="height: 270px; margin-top: 20px"></div>
<ul class="xx-small">
<li>Stack</li>
<ul>
<li>Contains frames, i.e. function parameters and local variables</li>
</ul>
<li>Heap</li>
<ul>
<li>Objects are allocated in a heap, a region of memory.</li>
</ul>
<li>Queue</li>
<ul>
<li>A list of messages to be processed</li>
<li>Message is <i>data</i> and <i>callback</i> to be processed</li>
</ul>
</ul>
</div>
<div class="slide">
<hgroup>
<h1>Stack</h1>
</hgroup>
<ul class="xx-small">
<li>When running a program...</li>
<pre class="brush: js; class-name: ''">
function foo(b) {
let a = 10
return a + b + 11
}
function bar(x) {
let y = 3
return foo(x * y)
}
console.log(bar(7)) //returns 42</pre>
<ol style="margin-left: -40px">
<li>calling <code>bar</code>: a frame is created with bar's arguments and variables.</li>
<li><code>bar</code> calls <code>foo</code>: a new frame with foo's args and vars is created.</li>
<li><code>foo</code> returns: the top frame element is popped out of the stack.</li>
<li><code>bar</code> returns: the stack is empty.</li>
</ol>
</ul>
</div>
<div class="slide">
<hgroup>
<h1>Event Loop</h1>
</hgroup>
<ul class="xx-small">
<li>Event loop</li>
<pre class="brush: js; class-name: ''">
while (queue.waitForMessage()) {
queue.processNextMessage()
}</pre>
<ul>
<li>Message = data + callback to be processed</li>
<li>Messages are process completely one by one</li>
<ul>
<li>No "clashes" across messages' processing</li>
<li>Processing should not block for a long time – Workers</li>
</ul>
<li>Brwoser adds a new message when an event occurs and there is an event listener</li>
</ul>
<li>Run-to-completion</li>
<ul>
<li>Each message is processed fully before any other message is processed.</li>
<li>A function runs entirely before any other code runs</li>
<ul>
<li>unlike in preemtive multitasking</li>
</ul>
<li>If a message takes much time to complete, all work can be blocked!</li>
</ul>
</ul>
</div>
<div class="slide">
<hgroup>
<h1>Handling Request</h1>
</hgroup>
<div class="h-drawing" style="text-align: left; height: 425px"
id="1aenRIcg3RqexY-9a1i0Bu2yWKzpSe0j9ULQ9u-gxNis"></div>
</div>
<div class="slide">
<hgroup>
<h1>Multiple Runtimes</h1>
</hgroup>
<ul class="x-small">
<li>Runtime</li>
<ul>
<li>Stack, Heap, Message Queue</li>
<li><code>iframe</code> and a Web worker has its own runtimes</li>
</ul>
<li>Communication between runtimes</li>
<ul>
<li>Runtimes communicate via <code>postMessage</code></li>
<li>A runtime can receive a message if it listens to message events</li>
</ul>
</ul>
</div>
<div class="slide">
<hgroup>
<h1>Web Workers</h1>
</hgroup>
<ul class="xx-small">
<li>A code that runs in a worker thread</li>
<ul>
<li>Every worker runs event loop; communicate via posting messages</li>
<li>Can do anything, but manipulate DOM</li>
<li>Can spawn a new workers</li>
<li>They are thread-safe</li>
</ul>
<li>Workers Types</li>
<ul>
<li>Dedicated workers – accessible by scripts that created them</li>
<li>Shared workers – accessible by multiple scripts (iframes, windows, workers)</li>
</ul>
</ul>
<ul class="xx-small">
<li>Example</li>
<pre class="brush: js; class-name: ''">
// main.js
var myWorker = new Worker('worker.js');
something.onchange = function() {
myWorker.postMessage([value1,value2]);
}
// worker.js
onmessage = function(e) {
var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
postMessage(workerResult);
}
// ... and terminate
myWorker.terminate()</pre>
</ul>
</div>
<div class="slide">
<hgroup>
<h1>Node.js</h1>
</hgroup>
<ul class="x-small">
<li><span id="nodejs" class="h-ref">Node.js</span></li>
<ul>
<li>Web server technology, very efficient and fast!</li>
<li>Event-driven I/O framework, based on JavaScript V8 engine</li>
<ul>
<li>Any I/O is non-blocking (it is asynchronous)</li>
</ul>
<li>One worker thread to process requests</li>
<ul>
<li>You do not need to deal with concurrency issues</li>
</ul>
<li>More threads to realize I/O</li>
<li>Open sourced, <span id="nodejs-github" class="h-ref">@GitHub</span>, many <span id="nodejs-libs"
class="h-ref">libraries</span></li>
<li>Future platform for Web 2.0 apps</li>
</ul>
<li>Every I/O as an event</li>
<ul>
<li>reading and writing from/to files</li>
<li>reading and writing from/to sockets</li>
<pre class="brush: js; class-name: ''">
// pseudo code; ask for the last edited time of a file
stat( 'somefile', function( result ) {
// use the result here
} );
</pre>
</ul>
</ul>
</div>
<div class="slide">
<hgroup>
<h1>Node.js Event Loop</h1>
</hgroup>
<ul class="xx-small">
<li>Allows Node.js to perform asynchronous I/O operations.</li>
<pre class="brush: bash; class-name: 'tight'; gutter: false;">
┌───────────────────────┐
┌─>│ timers │
│ └──────────┬────────────┘
│ ┌──────────┴────────────┐
│ │ I/O callbacks │
│ └──────────┬────────────┘
│ ┌──────────┴────────────┐
│ │ idle, prepare │
│ └──────────┬────────────┘ ┌───────────────┐
│ ┌──────────┴────────────┐ │ incoming: │
│ │ poll │<─────┤ connections, │
│ └──────────┬────────────┘ │ data, etc. │
│ ┌──────────┴────────────┐ └───────────────┘
│ │ check │
│ └──────────┬────────────┘
│ ┌──────────┴────────────┐
└──┤ close callbacks │
└───────────────────────┘
</pre>
<ul>
<li>Six phases, each phase has a FIFO queue of callbacks to execute.</li>
<ul>
<li><b>timers</b> – executes callbacks sheduled by <code>setTimeout()</code> and
<code>setInterval()</code>
</li>
<li><b>I/O callbacks</b> – executes all I/O callbacks except close callbacks.</li>
<li><b>idle/prepare</b> – used internally</li>
<li><b>poll</b> – retrieve new I/O events</li>
<li><b>check</b> – invokes <code>setImmediate()</code> callbacks</li>
<li><b>close callbacks</b> – executes close callback, e.g. socket.on('close', ...).</li>
</ul>
</ul>
</ul>
</div>
<div class="slide">
<hgroup>
<h1>HTTP Server in Node.js</h1>
</hgroup>
<ul class="x-small">
<li>HTTP Server implementation</li>
<ul>
<li>server running at <code>127.0.0.1</code>, port <code>8080</code>.</li>
<pre class="brush: js; class-name: ''">
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
</pre>
</ul>
</ul>
</div>
<div class="slide">
<hgroup>
<h1>Google Apps Script</h1>
</hgroup>
<ul class="xx-small">
<li><span id="gas" class="h-ref">Google Apps Script</span></li>
<ul>
<li>JavaScript cloud scripting language</li>
<li>easy ways to automate tasks across Google products and third party services</li>
</ul>
<li>You can</li>
<ul>
<li>Automate repetitive processes and workflows</li>
<li>Link Google products with third party services</li>
<li>Create custom spreadsheet functions</li>
<li>Build rich graphical user interfaces and menus</li>
</ul>
<pre class="brush: js; class-name: ''">
// create spreadsheet menu
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [ {name: "Say Hi", functionName: "sayHi"},
{name: "Say Hello", functionName: "sayHello"} ];
ss.addMenu("Tutorial", menuEntries);
}
function sayHi() {
Browser.msgBox("Hi");
}
function sayHello() {
Browser.msgBox("Hello");
}
</pre>
</ul>
</div>
</section>
<div class="slide outline"></div>
<section>
<header>JavaScript Language Overview</header>
<div class="slide">
<hgroup>
<h1>Objects and Arrays</h1>
</hgroup>
<ul class="xx-small">
<li>Objects and Arrays</li>
<pre class="brush: js; class-name: 'tight'">
// objects - key/value pairs
var obj = { name: "Tomas", "main-city" : "Innsbruck", value : 3 };
obj.name = "Peter"; // assign the name property another value
obj["main-city"] = "Prague"; // another way to access object's values; it's not an array!
// arrays
var a = ["Tomas", "Peter", "Alice"];
for (var i = 0; i < a.length; i++)
// do something with a[i]
// combinations of arrays and objects
var obj_a = [
{ name: "Tomas", city: "Innsbruck" },
{ name : "Peter", city : "Prague" },
{ name : "Alice", cities : ["Prague", "Brno"] } ];
for (var j = 0; j < obj_a.length; j++)
// do something with obj_a[j].name, ...
</pre>
<li>Functions</li>
<pre class="brush: js; class-name: 'tight'">
// assign a function to a variable
var minus = function(a, b) {
return a - b;
}
// call the function;
// now you can pass 'minus' as a parameter to another function
var r2 = minus(6, 4);
</pre>
</ul>
</div>
<div class="slide">
<hgroup>
<h1>Functions</h1>
</hgroup>
<ul class="xx-small">
<li>Function Callbacks</li>
<ul>
<li>You can use them to handle asynchronous events occurrences</li>
</ul>
<pre class="brush: js; class-name: 'tight'">
// function returns the result through a callback, not directly;
// this is not a non-blocking I/O, just demonstration of the callback
function add(a, b, callback) {
callback(a + b);
}
// assign the callback to a variable
var print = function(result) {
console.log(result);
};
// call the function with callback as a parameter
add(7, 8, print);
</pre>
<li>Functions as values in object</li>
<pre class="brush: js; class-name: 'tight'">
var obj = {
data : [2, 3, "Tomas", "Alice", 4 ],
getIndexdOf : function(val) {
for (var i = 0; i < this.data.length; i++)
if (this.data[i] == val)
return i;
return -1;
}
}
obj.getIndexOf(3); // will return 1
</pre>
</ul>
</div>
<div class="slide">
<hgroup>
<h1>Closures</h1>
</hgroup>
<ul class="xx-small">
<li>Closures</li>
<ul>
<li>A function value that references variables from outside its body</li>
</ul>
<pre class="brush: js; class-name: 'tight'">
function adder() {
var sum = 0;
return function(x) {
sum += x;
return sum;
}
}
var pos = adder();
console.log(pos(3)); // returns 3
console.log(pos(4)); // returns 7
console.log(pos(5)); // returns 12
</pre>
</ul>
</div>
<div class="slide">
<hgroup>
<h1>Objects</h1>
</hgroup>
<ul class="xx-small">
<li><code>this</code> problem</li>
<ul>
<li>A new function defines its own <code>this</code> value.</li>
</ul>
<pre class="brush: js; class-name: 'tight'">
function Person() {
// The Person() constructor defines `this` as an instance of itself.
this.age = 0;
setInterval(function growUp() {
// the growUp() function defines `this` as the global object,
// which is different from the `this`
// defined by the Person() constructor.
this.age++;
}, 1000);
}
var p = new Person();
</pre>
<ul>
<li>Solution</li>
</ul>
<pre class="brush: js; class-name: 'tight'">
function Person() {
var that = this;
that.age = 0;
setInterval(function growUp() {
// The callback refers to the `that` variable of which
// the value is the expected object.
that.age++;
}, 1000);
}
</pre>
</ul>
</div>
<div class="slide">
<hgroup>
<h1>Arrow Functions</h1>
</hgroup>
<ul class="xx-small">
<li>Arrow function expression</li>
<ul>
<li>defined in ECMAScript 2015</li>
<li>shorter syntax than a function expression</li>
<li>non-binding of <code>this</code></li>
</ul>
<pre class="brush: js; class-name: 'tight'">
function Person(){
this.age = 0;
setInterval(() => {
this.age++; // |this| now refers to the person object
}, 1000);
}
var p = new Person();
</pre>
<li>Syntax, function body</li>
<pre class="brush: js; class-name: 'tight'">
// concise body syntax, implied "return"
var func = x => x * x;
// with block body, explicit "return" required
var func = (x, y) => { return x + y; };
// object literal needs to be wrapped in parentheses
var func = () => ({foo: 1});
</pre>
</ul>
</div>
<div class="slide">
<hgroup>
<h1>Callback Hell</h1>
</hgroup>
<ul class="xx-small">
<li>Callback in callback</li>
<ul>
<pre class="brush: js; class-name: 'tight'">
loadScript('/my/script1.js', function(script) {
loadScript('/my/script2.js', function(script) {
loadScript('/my/script3.js', function(script) {
// ...continue after all script 1,2 and 3 are loaded
});
})
});</pre>
<li>Complex asnychronous code is hard to understand and manage</li>
</ul>
<li>Solution</li>
<ul>
<li>Promise – a proxy to a "future" value of the function</li>
<li>Async/await – language constructs to work with asynchronous code</li>
</ul>
</ul>
</div>
<div class="slide">
<hgroup>
<h1>Promise Object</h1>
</hgroup>
<ul class="xx-small">
<li>Promise</li>
<ul>
<li>An object representing <i>completion</i> or <i>failure</i> of an asynchronous operation.</li>
<li>A proxy for a value not necessarily known when the promise is created.</li>
<img src="img/promises.png" style="zoom: 0.8"></img>
</ul>
</ul>
</div>
<div class="slide">
<hgroup>
<h1>Callback Hell Example</h1>
</hgroup>
<ul class="xx-small">
<li>A callback in a callback</li>
<pre class="brush: js; class-name: 'tight'">
const request = require('request');
request("http://w20.vitvar.com/toc.json", { json: true },
(err, res, body) => {
if (err)
console.log("error: " + err)
else {
console.log(body)
request("http://mdw.vitvar.com/toc.json", { json: true },
(err, res, body) => {
if (err)
console.log("error: " + err)
else
console.log(body)
})
}
})</pre>
</div>
<div class="slide">
<hgroup>
<h1>Promise Example</h1>
</hgroup>
<ul class="xx-small">
<li>A chain of Promise objects</li>
<pre class="brush: js; class-name: 'tight'">
const request = require('request');
function get_json(url) {
return new Promise((resolve,reject)=>{
request(url, { json: true }, (err, res, body) => {
if (err)
reject(err)
else
resolve(body)
})
})
};
get_json('http://w20.vitvar.com/toc.json')
.then((data)=>{
console.log(data)
return get_json('http://mdw.vitvar.com/toc.json')
})
.then((data)=>{
console.log(data)
})
.catch((err)=>{
console.log("error: " + err)
})</pre>
</div>
<div class="slide">
<hgroup>
<h1>async/await</h1>
</hgroup>
<ul class="xx-small">
<li><code>async</code></li>
<ul>
<li>the function always returns a Promise</li>
<li>if there is no Promise, the returned value is wrapped into Promise</li>
</ul>
<pre class="brush: js; class-name: 'tight'">
async function f() {
return 1;
}
f().then((v) => alert(v));</pre>
<li><code>await</code></li>
<ul>
<li>makes program to wait until the promise is resolved or rejected</li>
<li>it returns the resolved value and throws an exception when the promise is rejected</li>
<li>can only be usded inside <code>async</code> function</li>
</ul>
<pre class="brush: js; class-name: 'tight'">
async function f() {
var promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("done!"), 1000)
});
var result = await promise; // wait untill the promise is resolved
alert(result);
}
f();</pre>
</ul>
</div>
</section>
</body>
</html>