1、迭代器
var arr = [1, 2, 3];
var iterator = arr[Symbol.iterator]();
iterator.next();
// { value: 1, done: false }
iterator.next();
// { value: 2, done: false }
iterator.next();
// { value: 3, done: false }
iterator.next();
// { value: undefined, done: true }
2、模拟迭代器
interface INext {
done: boolean
value: any
}
//有这个特性,那么就可以模拟map方法
class IteratorFromArray {
private currentArray: Array<unknown>
private cursor: number = 0
public constructor(arr: Array<unknown>) {
this.currentArray = arr
}
public next(): INext {
return this.cursor < this.currentArray.length
? { done: false, value: this.currentArray[this.cursor++] }
: { done: true, value: undefined }
}
public map(callback: (value: any) => any) {
let iterator = new IteratorFromArray(this.currentArray)
return {
next: () => {
const { done, value } = iterator.next()
return {
done,
value: done ? undefined : callback(value),
}
},
}
}
}
let arr = [1, 2, 3, 4, 5, 6]
let i = new IteratorFromArray(arr)
let newArr = i.map((val) => val + 1)
newArr.next()
// { value: 2, done: false }
newArr.next()
// { value: 3, done: false }
newArr.next()
// { value: 4, done: false }
newArr.next()
// { value: 5, done: false }
newArr.next()
// { value: 6, done: false }
newArr.next()
// { value: undefined, done: true }
3、入门案例
import * as Rx from 'rxjs'
let observable = new Rx.Observable((observer) => {
console.log('test')
observer.next('bill')
observer.next('ven')
setTimeout(() => {
observer.next('even')
})
})
console.log('start')
observable.subscribe((value) => {
console.log(value)
})
console.log('end')
/* 输出顺序, 说明其不仅可以处理同步的问题也可以处理异步的问题
* start
* bill
* ven
* end
* even
*/
注意:严格说来,这个的使用是一个观察者模式
观察者的三个方法
next: 每当Observable发出新的值, next方法就会被呼叫
complete: 在Observable没有其他的资料可以取得时, complete方法就会被呼叫,在complete被呼叫之后,next方法就不会再起作用
error: 每当Observable内发生错误时, error方法就会被呼叫
import { Observable } from 'rxjs';
const observable = new Observable(function subscribe(subscriber) {
try {
subscriber.next(1);
subscriber.next(2);
subscriber.next(3);
subscriber.complete();
} catch (err) {
subscriber.error(err); // delivers an error if it caught one
}
});
const subscription = observable.subscribe(x => console.log(x));
注意:监听函数如果只是一个函数,那么,error时,错误会被抛出, complete时,则会停止执行下面的next呼叫
import * as Rx from 'rxjs'
let observable = new Rx.Observable((observer) => {
console.log('test')
observer.next('bill')
observer.error('this is error')
observer.complete()
observer.next('ven')
setTimeout(() => {
observer.next('even')
})
})
let observe = {
next(...rest: any[]) {
console.log('this is next', rest)
},
complete(...rest: any[]) {
console.log('this is complete', rest)
},
error(...rest: any[]) {
console.log('this is error', rest)
},
}
observable.subscribe(observe)
// test
// this is next ['bill']
// this is error ['this is error']
注意:如果使用该方法,那么对应的方法会在对应钩子中执行
观察者的注销
import { Observable } from 'rxjs'
const observe = new Observable((subscriber) => {
let num = 1
subscriber.next(num)
let a = setInterval(() => {
subscriber.next(num++)
}, 1000)
return function unsubscribe() { // 如果有返回函数,那么这个函数会在取消监听的时候被执行
console.log('aaaaaaaaaaa')
}
})
let subscribe = observe.subscribe((...args: any[]) => { // 返回一个句柄,方便进行函数的注销
console.log(args)
})
console.log(subscribe.unsubscribe)
console.log(observe)
4、Creation Operator
Observable有许多创建实例的方法,称为 creation operator。下面我们列出RxJS常用的creation operator
of
import * as Rx from 'rxjs'
let observable = Rx.of('first', 'second', 'third', 'forth')
let observe = {
next(msg: string) {
console.log(msg)
},
complete() {
console.log('complete!!')
},
error(msg: string) {
console.log(msg)
},
}
observable.subscribe(observe)
// first
// second
// third
// complete!!
选择传递执行了'first', 'second' 然后结束(complete) , 这是一个十分觉模式。当我们想要同步的传递几个值时,就可以用of这个operator来简洁的表达
from
其实of的每一个参数合起来就是一个list,那么如果需要把array可枚举的参数传入,那么就可以使用from来处理
import * as Rx from 'rxjs'
import { map } from 'rxjs/operators'
//处理所有可遍历的数据
let observable = Rx.from(['aaa', 'bbb']).pipe(map((v) => v + 'c')) //使用数组并且使用枚举进行过滤
// let observable = Rx.of(new Set(['aa', 'bb']))
// let observable = Rx.from(
// new Map([
// ['a', 'aaa'],
// ['b', ' bbb'],
// ])
// )
let observe = {
next(msg: unknown) {
console.log(msg)
},
complete() {
console.log('complete!!')
},
error(msg: string) {
console.log(msg)
},
}
observable.subscribe(observe)
from也可以处理异步事件
import * as Rx from 'rxjs'
import { map } from 'rxjs/operators'
//处理异步事件
let observable = Rx.from(
new Promise((resolve) => {
setTimeout(() => resolve('ok'), 1000)
})
)
let observe = {
next(msg: unknown) {
console.log(msg)
},
complete() {
console.log('complete!!')
},
error(msg: string) {
console.log(msg)
},
}
observable.subscribe(observe)
fromEvent
fromEvent的第一個参数要传入 DOM 物件,第二個参数要监听的事件名称。下面的程式会针对 body 的 click 事件做监听,每当点击 body 就会打印出 event
import * as Rx from 'rxjs'
//定制事件,第一个参数为dom节点,第二个参数为事件名称
let observable = Rx.fromEvent(document.body, 'click')
let observe = {
next(msg: unknown) {
console.log(msg)
}
}
observable.subscribe(observe)
concatAll
import { interval, of, Observable } from 'rxjs'
import { concatAll, take } from 'rxjs/operators'
let first = new Observable((subscript) => {
subscript.next('aaaa')
subscript.next('bbbb')
subscript.next('cccc')
subscript.next('dddd')
subscript.complete() // 注意concatAll在接次序调用的时候,当函数里有complete的时候才会往下执行
})
let second = new Observable((subscript) => {
subscript.next('!!!!')
subscript.next('@@@@')
subscript.next('####')
subscript.next('$$$$')
subscript.next('%%%%')
subscript.complete()
})
let third = interval(1000).pipe(take(4))
let result = of(third, first, second).pipe(concatAll())
result.subscribe((x) => {
console.log(x)
})
注意: concatAll在接次序调用的时候,当函数里有complete的时候才会往下执行