Skip to content

Commit 973f97c

Browse files
committed
binary draft
1 parent 7f9a1e2 commit 973f97c

File tree

38 files changed

+906
-312
lines changed

38 files changed

+906
-312
lines changed

1-js/11-async/03-promise-chaining/article.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,9 @@ new Promise(function(resolve, reject) {
6969

7070
The value returned by `.then` is a promise, that's why we are able to add another `.then` at `(2)`. When the value is returned in `(1)`, that promise becomes resolved, so the next handler runs with the value.
7171

72-
Please note: technically we can also add many `.then` to a single promise. This is not chaining:
72+
**A classic newbie error: technically we can also add many `.then` to a single promise. This is not chaining.**
7373

74+
For example:
7475
```js run
7576
let promise = new Promise(function(resolve, reject) {
7677
setTimeout(() => resolve(1), 1000);
@@ -92,7 +93,7 @@ promise.then(function(result) {
9293
});
9394
```
9495

95-
What we did here is just several handlers to one promise. They don't pass the result to each other, instead they process it idependantly.
96+
What we did here is just several handlers to one promise. They don't pass the result to each other, instead they process it independently.
9697

9798
Here's the picture (compare it with the chaining above):
9899

1-js/11-async/07-microtask-queue/article.md

+20-14
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
Promise handlers `.then`/`.catch`/`.finally` are always asynchronous.
55

6-
Even when a Promise is immediately resolved, the code on the lines *below* your `.then`/`.catch`/`.finally` may still execute first.
6+
Even when a Promise is immediately resolved, the code on the lines *below* your `.then`/`.catch`/`.finally` will still execute first.
77

88
Here's the code that demonstrates it:
99

@@ -23,11 +23,11 @@ Why `.then` triggered after? What's going on?
2323

2424
# Microtasks
2525

26-
Asynchronous tasks need proper management. For that, the standard specifies an internal queue `PromiseJobs`, more often called the "microtask queue" (v8 term).
26+
Asynchronous tasks need proper management. For that, the standard specifies an internal queue `PromiseJobs`, more often referred to as "microtask queue" (v8 term).
2727

2828
As said in the [specification](https://tc39.github.io/ecma262/#sec-jobs-and-job-queues):
2929

30-
- The queue is first-in-first-out: tasks that get enqueued first are run first.
30+
- The queue is first-in-first-out: tasks enqueued first are run first.
3131
- Execution of a task is initiated only when nothing else is running.
3232

3333
Or, to say that simply, when a promise is ready, its `.then/catch/finally` handlers are put into the queue. They are not executed yet. Javascript engine takes a task from the queue and executes it, when it becomes free from the current code.
@@ -58,7 +58,7 @@ Now the order is as intended.
5858

5959
Browser Javascript, as well as Node.js, is based on an *event loop*.
6060

61-
"Event loop" is a process when the engine sleeps waits for events.
61+
"Event loop" is a process when the engine sleeps and waits for events, then reacts on those and sleeps again.
6262

6363
Examples of events:
6464
- `mousemove`, a user moved their mouse.
@@ -71,9 +71,11 @@ Things happen -- the engine handles them -- and waits for more to happen (while
7171

7272
![](eventLoop.png)
7373

74-
When an event happens, and the engine is busy, it gets into a so-called "macrotask queue" (v8 term).
74+
As you can see, there's also a queue here. A so-called "macrotask queue" (v8 term).
7575

76-
For instance, while the engine is busy processing a network `fetch`, a user may move their mouse causing `mousemove`, and `setTimeout` is due and so on, just as painted on the picture above.
76+
When an event happens, and the engine is busy, the event is enqueued.
77+
78+
For instance, while the engine is busy processing a network `fetch`, a user may move their mouse causing `mousemove`, and `setTimeout` may be due and so on, just as painted on the picture above.
7779

7880
Events from the macrotask queue are processed on "first came – first served" basis. When the engine browser finishes with `fetch`, it handles `mousemove` event, then `setTimeout` handler, and so on.
7981

@@ -120,20 +122,24 @@ Promise.resolved()
120122

121123
Naturally, `promise` shows up first, because `setTimeout` macrotask awaits in the less-priority macrotask queue.
122124

125+
**As a side effect, macrotasks are handled only when promises give the engine a "free time".**
126+
127+
So call have a promise chain that doesn't wait for anything, then things like `setTimeout` or event handlers can never get in the middle.
128+
123129
## Summary
124130

125-
Promise handling is always asynchronous, as all promise actions pass through the internal "promise jobs" queue, also called "microtask queue" (v8 term).
131+
- Promise handling is always asynchronous, as all promise actions pass through the internal "promise jobs" queue, also called "microtask queue" (v8 term).
126132

127-
**So, `.then/catch/finally` is called after the current code is finished.**
133+
**So, `.then/catch/finally` is called after the current code is finished.**
128134

129-
If we need to guarantee that a piece of code is executed after `.then/catch/finally`, it's best to add it into a chained `.then` call.
135+
If we need to guarantee that a piece of code is executed after `.then/catch/finally`, it's best to add it into a chained `.then` call.
130136

131-
There's also a "macrotask queue" that keeps various events, network operation results, `setTimeout`-scheduled calls, and so on. These are also called "macrotasks" (v8 term).
137+
- There's also a "macrotask queue" that keeps various events, network operation results, `setTimeout`-scheduled calls, and so on. These are also called "macrotasks" (v8 term).
132138

133-
The engine uses the macrotask queue to handle them in the appearance order.
139+
The engine uses the macrotask queue to handle them in the appearance order.
134140

135-
**Macrotasks run after the code is finished *and* after the microtask queue is empty.**
141+
**Macrotasks run after the code is finished *and* after the microtask queue is empty.**
136142

137-
In other words, they have lower priority.
143+
In other words, they have lower priority.
138144

139-
So the order is: regular code, then promise handling, then everything else.
145+
So the order is: regular code, then promise handling, then everything else, like events etc.

1-js/11-async/08-async-await/article.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ async function f() {
307307
})();
308308
```
309309
310-
There's no ambiguity here: `await` always finishes first.
310+
There's no ambiguity here: `await` always finishes first, because (as a microtask) it has a higher priority than `setTimeout` handling.
311311
312312
## Summary
313313

2-ui/5-data-storage/03-indexeddb/article.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ libs:
77

88
IndexedDB is a built-in database, much more powerful than `localStorage`.
99

10-
- Also key/value storage, but not only strings: value can be (almost) anything, multiple key types.
10+
- Key/value storage not only strings: value can be (almost) anything, multiple key types.
1111
- Supports transactions for reliability.
1212
- Supports key range queries, indexes.
1313
- Can store much more data than `localStorage`.
@@ -16,7 +16,7 @@ That power is usually excessive for traditional client-server apps. IndexedDB is
1616

1717
The native interface to IndexedDB, described in the specification <https://www.w3.org/TR/IndexedDB>, is event-based.
1818

19-
We can also use `async/await`-based interface with the help of a promise-based wrapper, like <https://github.com/jakearchibald/idb>. That's really convenient, but the wrapper is not perfect, it can't replace events for all cases, so we'll start with events, and then use the wrapper.
19+
We can also use `async/await` with the help of a promise-based wrapper, like <https://github.com/jakearchibald/idb>. That's pretty convenient, but the wrapper is not perfect, it can't replace events for all cases, so we'll start with events, and then use the wrapper.
2020

2121
## Open database
2222

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
function concat(arrays) {
2+
// sum of individual array lengths
3+
let totalLength = arrays.reduce((acc, value) => acc + value.length, 0);
4+
5+
if (!arrays.length) return null;
6+
7+
let result = new Uint8Array(totalLength);
8+
9+
// for each array - copy it over result
10+
// next array is copied right after the previous one
11+
let length = 0;
12+
for(let array of arrays) {
13+
result.set(array, length);
14+
length += array.length;
15+
}
16+
17+
return result;
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
function concat(arrays) {
2+
// ...your code...
3+
}
4+
5+
let chunks = [
6+
new Uint8Array([0, 1, 2]),
7+
new Uint8Array([3, 4, 5]),
8+
new Uint8Array([6, 7, 8])
9+
];
10+
11+
console.log(Array.from(concat(chunks))); // 0, 1, 2, 3, 4, 5, 6, 7, 8
12+
13+
console.log(concat(chunks).constructor.name); // Uint8Array
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
describe("concat", function() {
2+
let chunks = [
3+
new Uint8Array([0, 1, 2]),
4+
new Uint8Array([3, 4, 5]),
5+
new Uint8Array([6, 7, 8])
6+
];
7+
8+
it("result has the same array type", function() {
9+
10+
let result = concat(chunks);
11+
12+
assert.equal(result.constructor, Uint8Array);
13+
});
14+
15+
it("concatenates arrays", function() {
16+
17+
let result = concat(chunks);
18+
19+
assert.deepEqual(result, new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8]));
20+
21+
});
22+
23+
it("returns empty array on empty input", function() {
24+
25+
let result = concat([]);
26+
27+
assert.equal(result.length, 0);
28+
29+
});
30+
31+
});

6-binary/01-arraybuffer-and-views/01-concat/solution.md

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
# Concatenate typed arrays
3+
4+
Given an array of `Uint8Array`, write a function `concat(arrays)` that returns a concatenation of them into a single array.
Loading
Loading

0 commit comments

Comments
 (0)