-
Notifications
You must be signed in to change notification settings - Fork 1
/
Notes.txt
307 lines (221 loc) · 11.7 KB
/
Notes.txt
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
# Set up typescript environment
1. Install node js
On mac, use: brew install node
2. Install typescript using npm. (npm should be already installed with node js)
npm
# Questions and Tips:
1. Eslint vs Tslint?
Tslint is deprecated. Use Eslint.
2. commond js vs Javascript modules
CommonJs: created by node js;
module.exports is specific to node js;
Not natively understood by browsers; it requires either a loader library or some transpiling;
ES2015...
3. package-lock.json?
package-lock.json is automatically generated for any operations where npm modifies either the node_modules tree, or package.json. It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates.
This file is intended to be committed into source repositories, and serves various purposes...
References: https://docs.npmjs.com/cli/v7/configuring-npm/package-lock-json
4. In typescript/javascript, there is big int type: created by appending n to the end of an integer literal
let bigNumber: bigint = 100n;
5. JavaScript is generally structurally typed: A style of programming where you just care that an object has certain properties, and not what its name is (nominal typing). Also called duck typing in some languages
example:
class Zebra
{
trot()
{
// ...
}
}
class Poodle
{
trot()
{
// ...
}
}
function ambleAround(animal: Zebra)
{
animal.trot()
}
let zebra = new Zebra;
let poodle = new Poodle;
ambleAround(zebra); // OK
ambleAround(poodle); // OK
All that matters is that both implement the function called trot
The exception to this rule is classes with private or protected fields: when checking whether or not a shape is assignable to a class, if the class has any private or pro tected fields and the shape is not an instance of that class or a subclass of that class, then the shape is not assignable to the class
TypeScript’s type system is structural, not nominal. The relationships between types are determined by the properties they contain, not whether they were declared with some particular relationship.
6. Typescript allow string + number unless enable some special checks
like "Hello" + 10 is correct.
7. Logical operator can be applied to other types like string
"hello" && 11 is allowed.
Logical And (&&): Starting from left and moving to the right, return the first operand that is falsy. If no falsy operand was found, return the latest operand.
Logical Or (||): Starting from left and moving to the right, return the first operand that is truthy. If no truthy operand was found, return the latest operand.
8. Rest parameters/arguments:
// A list of strings with at least 1 element
let friends: [string, ...string[]] = ['Sara', 'Tali', 'Chloe', 'Claire']
function sumVariadicSafe(...numbers: number[]): number { return numbers.reduce((total, n) => total + n, 0)
}
sumVariadicSafe(1, 2, 3) // evaluates to 6
9. Define function type:
type Log = (message: string, userId?: string) => void
Then Log is a function that takes string as 1st arg and other strings as optional arg and return nothing
10. Javascript does NOT support function overload: one function name must have one implementation. If not, the older one will be replaced by new one.
11. Generic functions: where <Type> appears matters
type Filter =
{
<T>(array: T[], f: (item: T) => boolean): T[]
}
type Filter<T> =
{
(array: T[], f: (item: T) => boolean): T[]
}
12. In Typescript, class can only extend one base class but can implements more than one interfaces.
Comparing to abstract class, interface doesn't generate javascript code and is only a model.
Abstract class will generate javascript code
13. type alias and interface are mostly the same
14. Mixin; Typescript can return a anonymous class, like
return class extends ...
15. Function type
Declare function:
// Named function
function greet(name: string):string { return 'hello ' + name
}
// Function expression
let greet2 = function(name: string) { return 'hello ' + name
}
// Arrow function expression
let greet3 = (name: string) => { return 'hello ' + name
}
// Shorthand arrow function expression
let greet4 = (name: string) => 'hello ' + name
// Function constructor
let greet5 = new Function('name', 'return "hello " + name')
Function's type/ call signature:
function add(num1: number, num2: number): number
{
return num1 + num2;
}
function add's signature in typescript:
(a: number, b: number) => number
16. Node js threading
reference: https://medium.com/@mohllal/node-js-multithreading-a5cd74958a67
17. Understand promises
https://nodejs.dev/learn/understanding-javascript-promises
When you create a new Promise, the executor function passed to Promise constructor will be exeucted immediately. Inside the executor, it need to either resolve or reject based on execution result.
resolve(<value>) or reject(<value>)
Here is value is passed to "then" method if you call something like:
<Promise Object>.then((<value>) => {/*function body*/});
if you await the promise, the returned value from await will be the value passed to resolve/reject
Useful stackoverflow question: https://stackoverflow.com/questions/29963129/is-the-promise-constructor-callback-executed-asynchronously
18. If a function is marked async, it always return a Promise even if it doesn't return explicitly. You can even omit the return statement.
const aFunction = async () => {
return 'test'
}
is same as
const aFunction = () => {
return Promise.resolve('test')
}
19. await and async function
The body of an async function can be thought of as being split by zero or more await expressions. Top-level code, up to and including the first await expression (if there is one), is run synchronously. In this way, an async function without an await expression will run synchronously. If there is an await expression inside the function body, however, the async function will always complete asynchronously.
references: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
20. Javascript will do async when it is necessary
example:
function main() {
return new Promise( resolve => {
console.log(3); // sync
resolve(4); // async, send 4 async
console.log(5); // sync, executed before console.log(r)
});
}
async function f(){
console.log(2); // sync
let r = await main(); // partly async
console.log(r); // async since after await, recieve 4 after main func is resolved
}
console.log(1);
f();
console.log(6);
Here the whole block of function f is not async. Please check comments;
The output is:
1
2
3
5
6
// Async happened, await for main()
4
Notice:
Even if you await for a promise, the code inside promise callback after resolve/reject will continue execution and finish before the code after await. Check this line "console.log(5)" in previous example.
To avoid surprises, functions passed to then() will never be called synchronously, even with an already-resolved promise:
21. Return value of a promise.then
references: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
22. Node js Event loop and worker pool
References: https://nodejs.org/en/docs/guides/dont-block-the-event-loop/
In short, NodeJs has a event loop and a worker pool. Event loop listens to a list of "file descriptor" (file here is not related to files in disk). These "file descriptors" correspond to network sockets, any files it is watching, and so on. When the operating system says that one of these file descriptors is ready, the Event Loop translates it to the appropriate event and invokes the callback(s) associated with that event. If some operations like DNS look up cannot be listened in OS level (For example, they are blocking I/O calls), then these time-consuming calls can be executed in worker thread, which is part of worker pool. When it finishes, it will raise event for Event loop to process the providing callback.
Good talk about event loop and worker pool referenced by node js official site:
https://www.youtube.com/watch?v=P9csgxBgaZ8
Slides: https://gist.github.com/sam-github/71d0ebf53a63ab7ca35a1eccc8536e47
Eventloop in details
References: https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/
23. setTimeout, Promise.resolve, process.nextTick, setImmediate
References: https://nodejs.dev/learn/understanding-process-nexttick
Every time the event loop takes a full trip, we call it a tick.
nextTick will put callback right after the current tick (current script file)
Promises that resolve before the current function ends will be executed right after the current function.
Calling setTimeout(() => {}, 0) will execute the function at the end of next tick, much later than when using nextTick() which prioritizes the call and executes it just before the beginning of the next tick.
A function passed to process.nextTick() is going to be executed on the current iteration of the event loop, after the current operation ends. This means it will always execute before setTimeout and setImmediate.
A setTimeout() callback with a 0ms delay is very similar to setImmediate(). The execution order will depend on various factors, but they will be both run in the next iteration of the event loop.
Time of execution: A < B means A executed earlier than B, then
nextTick < Promise.resolve < setTimeout
24. Avoid time consuming javascript in callbacks
References: https://nodejs.org/en/docs/guides/dont-block-the-event-loop/#how-careful-should-you-be
pay attention to:
Regular expression: REDOS attack
Some Node core modules: Encryption, Compression, File system, Child process
JSON operations like parse or stringify: parse large complex json from client could be a issue
25. Node js EventEmitter
EventEmitter.emit will call registered handlers synchronously. It just iterates an array of registered handlers and run them one by one.
26. super keyword cannot be used to access parent class member variables. To access parent class members, use this keyword. super can be used to access parent class member functions though.
If child class constructor have some member assignment after super(), and super() needs to call member functions that is overriden in child class, which uses the member value assigned after super(), then the value is undefined in super() call since it is not assigned yet. But if the call is in an async block (like after await), the value will be assigned properly since the code after await will be placed after the current event in event loop.
Example:
abstract class Parent
{
constructor() {
this.Init();
}
public strMember: string = "Parent";
public abstract Output(): void;
public async Init()
{
console.log("Parent Init function");
await new Promise( (resolve) => {
setTimeout(() => {
resolve("Init promise");
}, 2000);
});
this.Output(); // We will call Output implemented in child class, which uses childMember. If there is no await, then childMember is undefined here
}
}
class Child extends Parent
{
public childMember: string = "child";
constructor()
{
super();
console.log("after super");
this.childMember = "child assigned"; // here childMember is assigned after super()
}
public Output(): void
{
console.log("Output in child");
console.log(this.childMember);
//super.Test();
//this.Test();
}
public Test(): void
{
console.log();
}
}
27. Do not create multiple promise all together and then await only one of them. It could lead to unhandeld rejected promise error since other non-awaited promise may reject.
example: https://stackoverflow.com/questions/67789309/why-do-i-get-an-unhandled-promise-rejection-with-await-promise-all