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.fromEvent(document, 'click').pipe(
map(i => i * 2),
filter(i => i > 5),
concat(
Observable.fromEvent(document, 'blur')
)
).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.fromEvent(document, 'click').pipe(
map(i => i * 2),
filter(i => i > 5),
concat(
Observable.fromEvent(document, 'blur')
)
)
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 = of([]);
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myInput = new FormControl;
results = of([]).pipe(
merge(this.myInput.valueChanges),
);
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myInput = new FormControl;
results = of([]).pipe(
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 = of([]).pipe(
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 = of([]).pipe(
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 = of([]).pipe(
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 = of([]).pipe(
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 = of([]).pipe(
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 = of([]).pipe(
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.pipe(
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.pipe(
map(p => p.name),
merge(this.myInput.valueChanges),
switchMap(name => this.user.search(name)),
);
constructor(
private route: ActivatedRoute,
private user: UserService,
) {}
}
@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.users.push({ name: 'new item' });
}
}
export class MyComponent {
myInput = new FormControl;
results = this.route.params.pipe(
map(p => p.name),
merge(this.myInput.valueChanges),
startWith('joão'),
switchMap(busca =>
)),
);
constructor(
private db: AngularFireDatabase,
private route: ActivatedRoute,
) {}
}
export class MyComponent {
myInput = new FormControl;
results = this.route.params.pipe(
map(p => p.name),
merge(this.myInput.valueChanges),
startWith('joão'),
switchMap(busca =>
this.db.list('/users', ref =>
ref.orderByChild('name')
.equalTo(busca)
)),
);
constructor(
private db: AngularFireDatabase,
private route: ActivatedRoute,
) {}
}
@Component()
export class UserAddressComponent {
constructor (
user: UserService,
address: AddressService,
) {
user.getCurrentUser().subscribe(user => {
})
}
}
@Component()
export class UserAddressComponent {
constructor (
user: UserService,
address: AddressService,
) {
user.getCurrentUser().pipe(
).subscribe(user => {
this.address = address;
})
}
}
@Component()
export class UserAddressComponent {
constructor (
user: UserService,
address: AddressService,
) {
user.getCurrentUser().subscribe(user => {
address.getAddressFromUser(user).subscribe(address => {
this.address = address;
})
})
}
}
@Component()
export class UserAddressComponent {
constructor (
user: UserService,
address: AddressService,
) {
user.getCurrentUser().pipe(
mergeMap(user => this.address.getAddressFrom(user))
).subscribe(address => {
this.address = address;
})
}
}
@Component()
export class MyComponent {
ngOnInit() {
interval(1000)
.subscribe(i => console.log(i));
}
}
@Component()
export class MyComponent {
unsubscribe = new Subject();
ngOnInit() {
interval(1000)
.subscribe(i => console.log(i));
}
ngOnDestroy() {
this.unsubscribe.next();
this.unsubscribe.complete();
}
}
@Component()
export class MyComponent {
unsubscribe = new Subject();
ngOnInit() {
interval(1000)
.pipe(takeUntil(this.unsubscribe))
.subscribe(i => console.log(i));
}
ngOnDestroy() {
this.unsubscribe.next();
this.unsubscribe.complete();
}
}
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.