markdown Angular2 Snippets - Observables

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown Angular2 Snippets - Observables相关的知识,希望对你有一定的参考价值。


## Observables

* An observable can be thought as data source. You use them to handle asynchronous tasks (as you do with callbacks or promises)
* Observer pattern: observable > stream/timeline of events/data packages > observer
* Three ways of handling data packages: data / error / completion. In this hooks is where your code gets executed, through anonymous callback functions for each case

For example in routing when we subscribe to route params:

```javascript
this.route.params
  .subscribe(
    (params: Params) => { // data 
      this.id = +params['id'];
    },
    () => { // error
    },
    () => { // completion
    }
  );
```

### Creating our first simple observable

* There are tons of different ways of creating an observable. Here we'll emit numbers on an interval:

```javascript
import { Observable } from 'rxjs/Observable';
import 'rxjs/Rx'; //we also need to import rxjs/Rx. In general you'll be working with the observables provided by angular. You only need this import when you want to work with observable operators, that are part of the rxjs library
...
ngOnInit() {
	// OBSERVABLE
    const myNumbers = Observable.interval(1000); //RxJS, has some methods for creating observables. 'interval' will emit a new piece of data every second
    // OBSERVER
    myNumbers.subscribe(
      (number: number) => {
        console.log(number);
      }
    );
  }
```

### Building an observable from scratch

* observable example that will fire after 2, 4 seconds, and then will fail.

```javascript

// 1) Create our custom observable
const myObservable = Observable.create((observer: Observer<string>) => { //'create' takes a function as argument, and this function should hold your asynchronous call. 
	// Receives an argument of type Observer. We are telling here to the observer when does it have to react. 
	// When you build an observable from scratch you need to build this bridge between the observable and the observer. 
	// We also configure the type of data it wille emit, a string
  setTimeout(() => {
    observer.next('first package'); //'next' emits a normal data package, pushes the next data package
  }, 2000);
  setTimeout(() => {
    observer.next('second package');
  }, 4000);
  setTimeout(() => {
    // observer.error('this does not work'); // emit an error
    observer.complete(); // emit completion
  }, 5000);
  setTimeout(() => {
    observer.next('third package'); // this never arrives as we've 'completed' the observable in the previous step
  }, 6000);
});

// 2) Subscribe to the observable
myObservable.subscribe(
  (data: string) => { console.log(data); },
  (error: string) => { console.log(error); },
  () => { console.log('completed'); }
);
```

### Unsubscribe

* Always unsubscribe from an observable when you leave the area where you are interested to be subscribed to it. For this, you need to store your subscriptions in properties of type `Subscription`:

```javascript
customObsSubscription: Subscription;
...
ngOnInit() {
  ...
  this.customObsSubscription = myObservable.subscribe(
    ...    
  );
}
```

Then unsubscribe from them onDestroy your component:

```javascript
ngOnDestroy() {
  this.customObsSubscription.unsubscribe();
}
```

** Observables built in in Angular clean themselves automatically**, but is a good practice to clean them on your own, and always when you're configuring your custom observables.

### Using subjects to pass and listen to data

* A subject is like an observable, but it allows you to conveniently push it to emit a new data during your code.

user.service.ts
```javascript
import { Subject } from 'rxjs/Subject';

export class UserService {
    userActivated = new Subject();
}
``` 

In our user component we'll use the service:

```javascript
`<button (click)="onActivate()">Activate</button>`

onActivate() {
    this.userService.userActivated.next(this.id); // A subject is the observable and the observer at the same time. 
    // Here we use the OBSERVER part, calling 'next' and passing a value, pushing a new data package
}
```

In our app component:

```javascript
<a>User 1 {{ user1activated ? '(Active)' : '' }}</a>
<a>User 2 {{ user2activated ? '(Active)' : '' }}</a>

user1activated = false;
user2activated = false;

ngOnInit() {
    this.userService.userActivated.subscribe( // userActivated is observer and observable at the same time, 
    	// here we use the OBSERVABLE part and subscribe to it
      (id: number) => {
        if (id === 1) {
          this.user1activated = true;
        } else if (id === 2) {
          this.user2activated = true;
        }
      }
    );
  }
```
* Can be compared to angular `EventEmitter` (indeed it is built on top of a `Subject`). Next time you want to do cross-component communication, is best practice to use `Subject` instead of `EventEmitter`, and use `next()` instead of `emit()` to push a new value, and `subscribe()` to consume it. You can also use the other functions (`complete`, `error`) and react to them. Also, don't forget to `unsubscribe` when done.


### Observable Operators

* RxJS operators allows you to transform the data you receive, and still stay inside the observable world. 
* Since Operators return new Observables, you can also chain these operators.

```javascript
// make sure you import 'rxjs/Rx'
const myNumbers = Observable.interval(1000)
  .map( //maps the data you get back, into a new observable with any transformation of your choice
    (data: number) => {
      return data * 2;
    }
  );
```

以上是关于markdown Angular2 Snippets - Observables的主要内容,如果未能解决你的问题,请参考以下文章

markdown [快照] #snippet

markdown Snippet Utile

markdown [查看寻呼机不完整,添加片段示例] #android_snippet #android

Visual Studio Code配置Markdown文档的snippet不生效的解决

markdown Angular2 Snippets - 路由

markdown Angular2 Snippets - Observables