Skip to content

Commit 1e18f27

Browse files
authored
slightly format functionalreactiveprogramming
1 parent 45639db commit 1e18f27

File tree

1 file changed

+39
-35
lines changed

1 file changed

+39
-35
lines changed

_chapters/functionalreactiveprogramming.md

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,13 @@ You could think of our lazy sequences as being “pull-based” data structures,
5353
Just as we have done for various data structures (arrays and so on) in previous chapters, we can define a transform over an Observable to create a new Observable. This transformation may have multiple steps the same way that we chained `filter` and `map` operations over arrays previously. In RxJS’s Observable implementation, however, they’ve gone a little bit more functional, by insisting that such operations are composed (rather than chained) inside a `pipe`. For example, here’s the squares of even numbers in the range [0,10):
5454

5555
```javascript
56-
const isEven = x=>x%2===0,
57-
square = x=>x*x
56+
const isEven = x => x%2 === 0,
57+
square = x => x*x
5858
range(10)
5959
.pipe(
6060
filter(isEven),
61-
map(square))
61+
map(square)
62+
)
6263
.subscribe(console.log)
6364
```
6465

@@ -87,9 +88,10 @@ To solve the first Project Euler problem using RxJS, we generate a sequence of n
8788
```javascript
8889
range(1000)
8990
.pipe(
90-
filter(x=> x%3===0 || x%5===0),
91-
scan((a,v)=>a+v),
92-
last())
91+
filter(x => x%3 === 0 || x%5 === 0),
92+
scan((a,v) => a+v),
93+
last()
94+
)
9395
.subscribe(console.log);
9496
```
9597

@@ -125,8 +127,8 @@ By contrast, the `mergeMap` operator gives the *Cartesian product* of two stream
125127

126128
```javascript
127129
columns.pipe(
128-
mergeMap(column=>rows.pipe(
129-
map(row=>[column, row])
130+
mergeMap(column => rows.pipe(
131+
map(row => [column, row])
130132
))
131133
).subscribe(console.log)
132134
```
@@ -147,8 +149,8 @@ If we contrast `mergeMap` and `map`, `map` will produce an Observable of Observa
147149

148150
```javascript
149151
columns.pipe(
150-
map(column=>rows.pipe(
151-
map(row=>[column, row])
152+
map(column => rows.pipe(
153+
map(row => [column, row])
152154
))
153155
).subscribe(console.log)
154156
```
@@ -191,7 +193,7 @@ The following lets us see in the console the keys pressed as they come in, it wi
191193

192194
```javascript
193195
key$.pipe(
194-
map(e=>e.key)
196+
map(e => e.key)
195197
).subscribe(console.log)
196198
```
197199

@@ -203,7 +205,7 @@ The following prints “!!” on every mousedown:
203205

204206
```javascript
205207
mouse$.pipe(
206-
map(_=>"!!")
208+
map(_ => "!!")
207209
).subscribe(console.log)
208210
```
209211

@@ -216,8 +218,8 @@ Once again this will keep producing the message for every mouse click for as lon
216218
The following achieves the same thing with a single subscription using `merge`:
217219

218220
```javascript
219-
merge(key$.pipe(map(e=>e.key)),
220-
mouse$.pipe(map(_=>"!!"))
221+
merge(key$.pipe(map(e => e.key)),
222+
mouse$.pipe(map(_ => "!!"))
221223
).subscribe(console.log)
222224
```
223225

@@ -266,7 +268,7 @@ Creating new Observable streams from existing streams
266268
merge<T, U...>(t: Observable<T>, u: Observable<U>, ...): Observable<T | U | ...>
267269

268270
// create n-ary tuples (arrays) of the elements at the head of each of the incoming streams
269-
zip<T, U...>(t: Observable<T>, r: Observable<U>):Observable<[T, U, ...]>
271+
zip<T, U...>(t: Observable<T>, r: Observable<U>): Observable<[T, U, ...]>
270272
```
271273
272274
### Observable methods
@@ -348,15 +350,15 @@ Here’s an event-driven code fragment that provides such dragging for some SVG
348350
```typescript
349351
const svg = document.getElementById("svgCanvas")!;
350352
const rect = document.getElementById("draggableRect")!;
351-
rect.addEventListener('mousedown',e => {
353+
rect.addEventListener('mousedown', e => {
352354
const
353355
xOffset = Number(rect.getAttribute('x')) - e.clientX,
354356
yOffset = Number(rect.getAttribute('y')) - e.clientY,
355-
moveListener = (e:MouseEvent)=>{
356-
rect.setAttribute('x',String(e.clientX + xOffset));
357-
rect.setAttribute('y',String(e.clientY + yOffset));
357+
moveListener = (e:MouseEvent) => {
358+
rect.setAttribute('x', String(e.clientX + xOffset));
359+
rect.setAttribute('y', String(e.clientY + yOffset));
358360
},
359-
done = ()=>{
361+
done = () => {
360362
svg.removeEventListener('mousemove', moveListener);
361363
};
362364
svg.addEventListener('mousemove', moveListener);
@@ -402,9 +404,9 @@ We now rewrite precisely the same behaviour using Observable FRP:
402404
x: clientX + mouseDownXOffset, // E
403405
y: clientY + mouseDownYOffset // N
404406
}))))) // C
405-
.subscribe(({x, y}) => { // Y
406-
rect.setAttribute('x', String(x)) // >-----------------------------|
407-
rect.setAttribute('y', String(y)) // >-----------------------------/
407+
.subscribe(({x, y}) => { // Y
408+
rect.setAttribute('x', String(x)) // >-----------------------------|
409+
rect.setAttribute('y', String(y)) // >-----------------------------/
408410
});
409411
```
410412

@@ -427,38 +429,38 @@ the position of the top-left corner of the rectangle, and (optionally, since it
427429

428430
```typescript
429431
type State = Readonly<{
430-
pos:Point,
431-
offset?:Point
432+
pos: Point,
433+
offset?: Point
432434
}>
433435
```
434436
435437
We’ll introduce some types to model the objects coming through the stream and the effects they have when applied to a `State` object in the `scan`. First, all the events we care about have a position on the SVG canvas associated with them, so we’ll have a simple immutable `Point` interface with `x` and `y` positions and a couple of handy vector math methods (note that these create a new `Point` rather than mutating any existing state within the `Point`):
436438
437439
```typescript
438440
class Point {
439-
constructor(public readonly x:number, public readonly y:number){}
440-
add(p:Point) { return new Point(this.x+p.x,this.y+p.y) }
441-
sub(p:Point) { return new Point(this.x-p.x,this.y-p.y) }
441+
constructor(public readonly x: number, public readonly y: number) {}
442+
add(p: Point) { return new Point(this.x + p.x,this.y + p.y) }
443+
sub(p: Point) { return new Point(this.x - p.x,this.y - p.y) }
442444
}
443445
```
444446

445447
Now we create a subclass of `Point` with a constructor letting us instantiate it for a given (DOM) `MouseEvent` and an `abstract` (placeholder) definition for a function to apply the correct update action to the `State`:
446448

447449
```typescript
448450
abstract class MousePosEvent extends Point {
449-
constructor(e:MouseEvent) { super(e.clientX, e.clientY) }
450-
abstract apply(s:State):State;
451+
constructor(e: MouseEvent) { super(e.clientX, e.clientY) }
452+
abstract apply(s: State): State;
451453
}
452454
```
453455

454456
And now two further subclasses with concrete definitions for `apply`.
455457

456458
```typescript
457459
class DownEvent extends MousePosEvent {
458-
apply(s:State) { return { pos: s.pos, offset: s.pos.sub(this) }}
460+
apply(s: State) { return { pos: s.pos, offset: s.pos.sub(this) } }
459461
}
460462
class DragEvent extends MousePosEvent {
461-
apply(s:State) { return { pos: this.add(s.offset), offset: s.offset }}
463+
apply(s: State) { return { pos: this.add(s.offset), offset: s.offset } }
462464
}
463465
```
464466

@@ -478,7 +480,8 @@ But now we’ll capture initial position of the rectangle one time only in an im
478480
const initialState: State = {
479481
pos: new Point(
480482
Number(rect.getAttribute('x')),
481-
Number(rect.getAttribute('y')))
483+
Number(rect.getAttribute('y'))
484+
)
482485
}
483486
```
484487

@@ -491,9 +494,10 @@ mousedown
491494
mergeMap(mouseDownEvent =>
492495
mousemove.pipe(
493496
takeUntil(mouseup),
494-
map(mouseDragEvent=>new DragEvent(mouseDragEvent)),
497+
map(mouseDragEvent => new DragEvent(mouseDragEvent)),
495498
startWith(new DownEvent(mouseDownEvent)))),
496-
scan((s: State, e: MousePosEvent) => e.apply(s),
499+
scan(
500+
(s: State, e: MousePosEvent) => e.apply(s),
497501
initialState))
498502
.subscribe(e => {
499503
rect.setAttribute('x', String(e.rect.x))

0 commit comments

Comments
 (0)