William Grasel PRO
Desenvolvedor Web, Google Developer Expert, Microsoft Most Valuable Professional, palestrante, consultor e coordenador do AngularSP.
@willgmbr
fb.me/wgrasel
- André Staltz
síncrono
assíncrono
múltiplo
único
processamento
valor
Objeto
Array
Promise
Observable
The ReactiveX library for JavaScript.
[1, 2, 3]
.map(i => i * 2) // [2, 4, 6]
.filter(i => i > 5) // [6]
.concat([10, 20, 30]) // [6, 10, 20, 30]
Observable.of(1, 2, 3)
.map(i => i * 2)
.filter(i => i > 5)
.concat(
Observable.of(10, 20, 30)
)
Observable.fromEvent(document, 'click')
.map(i => i * 2)
.filter(i => i > 5)
.concat(
Observable.fromEvent(document, 'blur')
)
Observable.from(function* (){ yield 9; })
.map(i => i * 2)
.filter(i => i > 5)
.concat(
Observable.from([10, 20, 30])
)
.subscribe(console.log)
Array.of(1, 2, 3)
.map(i => i * 2)
.filter(i => i > 5)
.concat(
Array.of(10, 20, 30)
)
Observable.interval(500)
.map(i => i * 2)
.filter(i => i > 5)
.concat(
Observable.of(10, 20, 30)
)
Observable.from(function* (){ yield 9; })
.map(i => i * 2)
.filter(i => i > 5)
.concat(
Observable.from([10, 20, 30])
)
Observable.from(Promise.resolve(1))
.concat(Promise.resolve(2))
.concat(Promise.resolve(3))
.subscribe(console.log); // 1, 2, 3
Observable.of(1, 2, 3)
.toPromise()
.then(console.log) // 3
Observable.of(1, 2, 3)
.first()
.toPromise()
.then(console.log) // 1
<input type="text" [(ngModel)]="myInput">
<ul>
<li *ngFor="let r of results">{{r.name}}</li>
</ul>
<input type="text" [formControl]="myInput">
<ul>
<li *ngFor="let r of results">{{r.name}}</li>
</ul>
<input type="text" [formControl]="myInput">
<ul>
<li *ngFor="let r of results | async">{{r.name}}</li>
</ul>
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myInput = new FormControl;
results = Observable.of([]);
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myInput = new FormControl;
results = Observable.of([])
.merge(this.myInput.valueChanges);
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myInput = new FormControl;
results = Observable.of([])
.merge(this.myInput.valueChanges)
.map(v => `https://swapi.co/api/people/?search=${v}`);
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myInput = new FormControl;
results = Observable.of([])
.merge(this.myInput.valueChanges)
.map(v => `https://swapi.co/api/people/?search=${v}`)
.mergeMap(url => this.http.get(url));
constructor(private http: HttpClient) {}
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myInput = new FormControl;
results = Observable.of([])
.merge(this.myInput.valueChanges)
.map(v => `https://swapi.co/api/people/?search=${v}`)
.switchMap(url => this.http.get(url))
.map(json => json['results']);
constructor(private http: HttpClient) {}
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myInput = new FormControl;
results = Observable.of([])
.merge(this.myInput.valueChanges)
.filter(v => v.length > 2)
.map(v => `https://swapi.co/api/people/?search=${v}`)
.switchMap(url => this.http.get(url))
.map(json => json['results']);
constructor(private http: HttpClient) {}
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myInput = new FormControl;
results = Observable.of([])
.merge(this.myInput.valueChanges)
.filter(v => v.length > 2)
.debounceTime(300)
.map(v => `https://swapi.co/api/people/?search=${v}`)
.switchMap(url => this.http.get(url))
.map(json => json['results']);
constructor(private http: HttpClient) {}
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myInput = new FormControl;
results = Observable.of([])
.merge(this.myInput.valueChanges)
.map(v => `https://swapi.co/api/people/?search=${v}`)
.mergeMap(url => this.http.get(url))
.map(json => json['results']);
constructor(private http: HttpClient) {}
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myInput = new FormControl;
results = Observable.of([])
.merge(this.myInput.valueChanges)
.filter(v => v.length > 2)
.debounceTime(300)
.map(v => `https://swapi.co/api/people/?search=${v}`)
.switchMap(url => this.http.get(url))
.map(json => json['results'])
.retry(3);
constructor(private http: HttpClient) {}
}
export class AppComponent {
results = this.route.params
.map(p => p.name)
.switchMap(name => this.user.search(name));
constructor(
private route: ActivatedRoute,
private user: UserService,
) {}
}
export class AppComponent {
myInput = new FormControl;
results = this.route.params
.map(p => p.name)
.merge(this.myInput.valueChanges)
.switchMap(name => this.user.search(name));
constructor(
private route: ActivatedRoute,
private user: UserService,
) {}
}
<ul>
<li *ngFor="let user of userList | async">
{{user.name}}
</li>
</ul>
<section *ngIf="userResult | async as user">
<div>{{user.name}}</div>
<div>{{user.age}}</div>
<div>{{user.email}}</div>
</section>
@Component({
template: `
<div *ngFor="let user of users | async">
{{ user.name }}
</div>`
})
export class MyComponent {
users = this.db.list('/users');
constructor(private db: AngularFireDatabase) {}
}
@Component({
template: `
<div *ngFor="let user of users | async">
{{ user.name }}
</div>`
})
export class MyComponent {
users = this.db.list('/users');
constructor(private db: AngularFireDatabase) {}
addItem() {
this.items.push({ name: 'new item' });
}
}
export class MyComponent {
myInput = new FormControl;
users = this.myInput.valueChanges
.merge(this.route.parms)
.startWith('joão')
.switchMap(busca =>
));
constructor(
private db: AngularFireDatabase,
private route: ActivatedRoute,
) {}
}
export class MyComponent {
myInput = new FormControl;
users = this.myInput.valueChanges
.merge(this.route.parms)
.startWith('joão')
.switchMap(busca =>
this.db.list('/users', ref =>
ref.orderByChild('name')
.equalTo(busca)
));
constructor(
private db: AngularFireDatabase,
private route: ActivatedRoute,
) {}
}
Input:
data
Output:
event
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { Observable } from 'rxjs/Rx';
@Component({
selector: 'count-3',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<p>Hey: {{ count | async }}</p>',
})
export class HeroAsyncMessageComponent {
count = Observable.interval(500).take(3).repeat();
}
Reactive Extensions for Angular
Compose and cancel async actions to create side effects and more.
By William Grasel
Passado o hype de programação reativa de uns cinco anos atrás, foi tempo suficiente para esse conceito e suas ferramentas amadurecerem em meio a comunidade. Nessa apresentação veremos técnicas avançadas de programação assíncrona, muito além de callbacks, promises e async/await, para domar todo tipo de fluxo de dados com facilidade, utilizando um pattern muito antigo chamado Observable. Tudo isso em meio a exemplos práticos com novas ferramentas para seu dia a dia!
Desenvolvedor Web, Google Developer Expert, Microsoft Most Valuable Professional, palestrante, consultor e coordenador do AngularSP.