├── .gitignore ├── 1. callbacks.js ├── 2. callbacks-rx.js ├── 4.file-example ├── reader.js └── writer.js ├── 5.catchError.js ├── 6.retry.js ├── 7.retry-when.js ├── README.md ├── package-lock.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | temp/ -------------------------------------------------------------------------------- /1. callbacks.js: -------------------------------------------------------------------------------- 1 | function getPhone(userId, callback) { 2 | setTimeout(() => { 3 | return callback(null, { 4 | ddd: 11, 5 | number: 112123123 6 | }) 7 | }, 1000); 8 | } 9 | 10 | function getAddress(userId, callback) { 11 | setTimeout(() => { 12 | return callback(null, { 13 | street: 'rua dos bobos', 14 | number: 0 15 | }) 16 | }, 1000); 17 | } 18 | 19 | function getUser(username, callback) { 20 | setTimeout(() => { 21 | return callback(null, { 22 | id: 1, 23 | username: '@erickwendel_' 24 | }) 25 | }, 1000); 26 | } 27 | 28 | (function main() { 29 | const stdin = process.openStdin() 30 | console.log('Digite um nome para pesquisar um usuario') 31 | stdin.on('data', (data) => { 32 | const username = data.toString().trim() 33 | console.log(`Pesquisando por ${username}... `) 34 | getUser(username, function resolveUser(error1, user) { 35 | getAddress(user.id, function resolveAddress(error2, address) { 36 | getPhone(user.id, function resolvePhone(error3, phone) { 37 | console.log( 38 | ` 39 | User: ${user.username}, 40 | Address: ${address.street}, ${address.number}, 41 | Phone: (${phone.ddd}) ${phone.number} 42 | `) 43 | }) 44 | }) 45 | }) 46 | }) 47 | })() 48 | 49 | -------------------------------------------------------------------------------- /2. callbacks-rx.js: -------------------------------------------------------------------------------- 1 | const Rx = require('rxjs') 2 | const { 3 | map, 4 | switchMap 5 | } = require('rxjs/operators') 6 | 7 | function getPhone(userId, callback) { 8 | setTimeout(() => { 9 | return callback(null, { 10 | ddd: 11, 11 | phone: 112123123 12 | }) 13 | }, 1000); 14 | } 15 | 16 | function getAddress(userId, callback) { 17 | setTimeout(() => { 18 | return callback(null, { 19 | street: 'rua dos bobos', 20 | number: 0 21 | }) 22 | }, 1000); 23 | } 24 | 25 | function getUser(username, callback) { 26 | setTimeout(() => { 27 | return callback(null, { 28 | id: 1, 29 | username: username || '@erickwendel_' 30 | }) 31 | }, 1000); 32 | } 33 | 34 | (function main() { 35 | const getAddressObs = Rx.bindNodeCallback(getAddress) 36 | const getPhoneObs = Rx.bindNodeCallback(getPhone) 37 | const getUserObs = Rx.bindNodeCallback(getUser) 38 | const concatObj = (prev) => map(current => Object.assign({}, current, prev)) 39 | 40 | const stdin = process.openStdin() 41 | console.log('Digite um nome para pesquisar um usuario') 42 | Rx.fromEvent(stdin, 'data') 43 | .pipe(switchMap(data => getUserObs(data.toString().trim()))) 44 | .pipe( 45 | switchMap(prev => 46 | getAddressObs(prev.id) 47 | .pipe(concatObj(prev)) 48 | ) 49 | ) 50 | .pipe( 51 | switchMap(prev => 52 | getPhoneObs(prev.id) 53 | .pipe(concatObj(prev)) 54 | ) 55 | ) 56 | .pipe( 57 | map(item => ` 58 | User: ${item.username} 59 | Address: ${item.street}, ${item.number} 60 | Phone: (${item.ddd}) ${item.phone} 61 | `) 62 | ) 63 | .subscribe(console.log) 64 | 65 | })() 66 | 67 | -------------------------------------------------------------------------------- /4.file-example/reader.js: -------------------------------------------------------------------------------- 1 | const Rx = require('rxjs'); 2 | const { 3 | readFile, 4 | watch, 5 | mkdir 6 | } = require('fs'); 7 | const { 8 | join 9 | } = require('path'); 10 | const { 11 | map, 12 | mergeMap, 13 | retry, 14 | catchError, 15 | delayWhen, 16 | tap, 17 | retryWhen 18 | } = require('rxjs/operators'); 19 | 20 | const watchDir = directory => { 21 | console.log(`Wating for changes at ${directory}`); 22 | return Rx.Observable.create(observer => { 23 | watch(directory, (eventType, filename) => { 24 | console.log(`Event raised! type: ${eventType}`); 25 | return observer.next({ 26 | eventType, 27 | filename: `${directory}/${filename.toString()}`, 28 | }); 29 | }); 30 | }); 31 | }; 32 | watchDir(join(__dirname, 'temp')) 33 | .pipe( 34 | mergeMap(e => Rx.bindNodeCallback(readFile)(e.filename)), 35 | retryWhen(errors => 36 | Rx.bindNodeCallback(mkdir)('temp') 37 | .pipe( 38 | //log error message 39 | tap(val => console.log(`Creating folder!`)), 40 | delayWhen(val => timer(0)), 41 | ), 42 | ) 43 | ) 44 | 45 | .pipe( 46 | map(JSON.parse), 47 | retry(error => Rx.of([])), 48 | ) 49 | .pipe(mergeMap(e => Rx.from(e))) 50 | 51 | .subscribe( 52 | result => { 53 | console.log(` 54 | ******** 55 | Nome: ${result.name}, 56 | Idade: ${result.age} 57 | `); 58 | }, 59 | error => console.error(`errror`, error), 60 | () => console.log('process finished!') 61 | ); -------------------------------------------------------------------------------- /4.file-example/writer.js: -------------------------------------------------------------------------------- 1 | const Rx = require('rxjs'); 2 | const { 3 | join 4 | } = require('path'); 5 | const { 6 | writeFile, 7 | } = require('fs'); 8 | 9 | const { 10 | map, 11 | mergeMap, 12 | toArray 13 | } = require('rxjs/operators'); 14 | 15 | const RANGE = 2; 16 | 17 | 18 | const write = item => 19 | Rx.bindNodeCallback(writeFile)( 20 | join(__dirname, `temp/file-${item.count}.json`), 21 | JSON.stringify(item.items), 22 | ); 23 | 24 | Rx.interval(1000) 25 | .pipe( 26 | mergeMap(e => 27 | Rx.range(0, RANGE) 28 | .pipe( 29 | map(index => ({ 30 | name: `Fulano ${index + e * RANGE}`, 31 | age: index * 2, 32 | })), 33 | toArray(), 34 | ) 35 | .pipe( 36 | map(item => ({ 37 | count: e, 38 | items: item 39 | })) 40 | ), 41 | ), 42 | ) 43 | .pipe(mergeMap(i => write(i).pipe(mergeMap(j => Rx.of(i))))) 44 | .subscribe(console.log, error => console.error('errouuuu', error.message)); -------------------------------------------------------------------------------- /5.catchError.js: -------------------------------------------------------------------------------- 1 | const { 2 | throwError, 3 | of 4 | } = require('rxjs'); 5 | const { 6 | catchError 7 | } = require('rxjs/operators'); 8 | 9 | //emit error 10 | const source = throwError('This is an error!'); 11 | 12 | const example = source.pipe( 13 | catchError(val => of (`I caught: ${val}`)) 14 | ); 15 | 16 | //output: 'I caught: This is an error' 17 | example.subscribe(val => console.log(val)); 18 | 19 | -------------------------------------------------------------------------------- /6.retry.js: -------------------------------------------------------------------------------- 1 | const { 2 | interval, 3 | of , 4 | throwError 5 | } = require('rxjs'); 6 | const { 7 | mergeMap, 8 | retry 9 | } = require('rxjs/operators'); 10 | 11 | //emit value every 1s 12 | const source = interval(1000); 13 | const example = source.pipe( 14 | mergeMap(val => { 15 | //throw error for demonstration 16 | if (val > 5) return throwError('Error!'); 17 | 18 | return of(val); 19 | }), 20 | //retry 2 times on error 21 | retry(2), 22 | ); 23 | /* 24 | output: 25 | 0..1..2..3..4..5.. 26 | 0..1..2..3..4..5.. 27 | 0..1..2..3..4..5.. 28 | "Error!: Retried 2 times then quit!" 29 | */ 30 | const subscribe = example.subscribe({ 31 | next: val => console.log(val), 32 | error: val => console.log(`${val}: Retried 2 times then quit!`), 33 | }); -------------------------------------------------------------------------------- /7.retry-when.js: -------------------------------------------------------------------------------- 1 | const { 2 | timer, 3 | interval 4 | } = require('rxjs'); 5 | const { 6 | map, 7 | tap, 8 | retryWhen, 9 | delayWhen 10 | } = require('rxjs/operators'); 11 | 12 | //emit value every 1s 13 | const source = interval(1000); 14 | const example = source.pipe( 15 | map(val => { 16 | if (val > 5) { 17 | //error will be picked up by retryWhen 18 | throw val; 19 | } 20 | return val; 21 | }), 22 | retryWhen(errors => 23 | errors.pipe( 24 | //log error message 25 | tap(val => console.log(`Value ${val} was too high!`)), 26 | //restart in 5 seconds 27 | delayWhen(val => timer(val * 1000)), 28 | ), 29 | ), 30 | ).subscribe(val => console.log(val));; 31 | /* 32 | output: 33 | 0 34 | 1 35 | 2 36 | 3 37 | 4 38 | 5 39 | "Value 6 was too high!" 40 | --Wait 5 seconds then repeat 41 | */ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RxJS examples 2 | 3 | ## Running the file-example 4 | 5 | - `node reader.js` 6 | - `node writer.js` 7 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rxjs-braziljs", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "double-ended-queue": { 8 | "version": "2.1.0-0", 9 | "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", 10 | "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" 11 | }, 12 | "redis": { 13 | "version": "2.8.0", 14 | "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", 15 | "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", 16 | "requires": { 17 | "double-ended-queue": "^2.1.0-0", 18 | "redis-commands": "^1.2.0", 19 | "redis-parser": "^2.6.0" 20 | } 21 | }, 22 | "redis-commands": { 23 | "version": "1.4.0", 24 | "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.4.0.tgz", 25 | "integrity": "sha512-cu8EF+MtkwI4DLIT0x9P8qNTLFhQD4jLfxLR0cCNkeGzs87FN6879JOJwNQR/1zD7aSYNbU0hgsV9zGY71Itvw==" 26 | }, 27 | "redis-parser": { 28 | "version": "2.6.0", 29 | "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", 30 | "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=" 31 | }, 32 | "rxjs": { 33 | "version": "6.3.3", 34 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", 35 | "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", 36 | "requires": { 37 | "tslib": "^1.9.0" 38 | } 39 | }, 40 | "tslib": { 41 | "version": "1.9.3", 42 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", 43 | "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rxjs-braziljs", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "example1.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "redis": "^2.8.0", 14 | "rxjs": "^6.3.3" 15 | } 16 | } 17 | --------------------------------------------------------------------------------