创建Observable

of

接收任意多个参数,参数可以是任意类型,用于创建简单的Observable

	of(1, 2, 3).subscribe(res => console.log(res))   		// 依次输出 1,2,3
	of([1, 2, 3]).subscribe(res => console.log(res)) 		// [1, 2, 3]
	of(true).subscribe(res => console.log(res))   			// true
	of('a', 'b', 'c').subscribe(res => console.log(res)) 	// 依次输出 'a', 'b', 'c'
	of({name: '诸葛亮', age: 18}, 'hello', 100).subscribe(res => console.log(res)) // 依次输出({name: '诸葛亮', age: 18}, 'hello', 100

from

接收一个数组、类数组对象、promise、迭代器对象或者类Observable对象作为参数,用来创建一个Observable

	from([1, 2, 3]).subscribe(res => console.log(res))   		// 依次输出 1,2,3
	from('hello').subscribe(res => console.log(res))   			// 依次输出 h,e,l,l,0
	from(of([1, 2, 3])).subscribe(res => console.log(res))  	// [1, 2, 3]
	from(new Promise((resolve) => resolve('ok'))).subscribe(res => console.log(res))   			//  ok
	from(true).subscribe(res => console.log(res))	// 报错ERROR TypeError: You provided 'true' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

fromEvent

根据目标和事件类型创建一个Observable

	const btn = document.getElementById('btn')
	fromEvent(btn, 'click').subscribe(res => console.log('点击'))

interval

创建一个Observable,根据给定时间间隔发出无限自增的序列整数。

	interval(1000).subscribe(res => console.log(res))	// 每间隔1秒依次输出0,1,2,3,4.....

timer

创建一个Observable,延迟指定的时间后,根据给定时间间隔发出无限自增的序列整数。

	timer(3000, 1000).subscribe(res => console.log(res))	// 延迟3秒以后,每间隔1秒依次输出0,1,2,3,4.....

forkJoin

用法类型Promise.all,接收一个数组作为参数以创建一个Observable,该数组元素的类型可以ObservablePromise

	const p = new Promise((resolve) => {
      setTimeout(() => {
        resolve('ok')
      }, 2000)
    })
    forkJoin([of(1), of(2), p, interval(1000).pipe(take(5))]).subscribe(res => console.log(res))      // 4s后输出[1, 2, 'ok', 4]

操作符

map

类似数组的map方法,在回调函数中对每一项进行操作。

	of(1, 2, 3).pipe(map(val => val * val)).subscribe(res => console.log(res)) // 依次输出1, 4, 9
	of(...[{name: '诸葛亮', age: 18}, {name: '孙悟空', age: 20}]).pipe(map(item => ({...item, sex: '男'}))).subscribe(res => console.log(res))	// 依次输出{name: "诸葛亮", age: 18, sex: "男"}, {name: "孙悟空", age: 20, sex: "男"}

	from([{name: '诸葛亮', age: 18}, {name: '孙悟空', age: 20}]).pipe(map(item => ({...item, sex: '男'}))).subscribe(res => console.log(res))// 依次输出{name: "诸葛亮", age: 18, sex: "男"}, {name: "孙悟空", age: 20, sex: "男"}

filter

类似数组的filter方法,对符合条件每一项进行过滤。

	from([1, 2, 3, 4, 5]).pipe(filter(val => val % 2 === 0)).subscribe(res => console.log(res))	// 依次输出2, 4

take

取指定数量的值进行发送。

	of(1, 2, 3, 4, 5).pipe(take(2)).subscribe(res => console.log(res))	// 1,2
	interval(1000).pipe(take(2)).subscribe(res => console.log(res))  //每间隔1s依次输出1,2

mergeMap

mergeMap回调函数返回的数据类型是observable

	// mergeMap一般用于数据项类型为observalbe的数组
	from([of(1), of(2), of(3)]).pipe(mergeMap(val => val.pipe(map(v => v * v)))).subscribe(res => console.log(res))	// 依次输出 1, 4, 9
	// 若数据项类型不是observalbe类型,可以在`mergeMap`回调函数返回,但是
	// 有点多此一举,可以直接使用map处理
	from([1, 2, 3]).pipe(mergeMap(val => of(val).pipe(map(v => v * v)))).subscribe(res => console.log(res))	// 依次输出 1, 4, 9处理
	// 有点多此一举了,可以直接使用filter
	from([1, 2, 3]).pipe(mergeMap(val => of(val).pipe(filter(v => v > 1)))).subscribe(res => console.log(res))	// 依次输出 2, 3

switchMap

switchMapmergeMap类似,区别是switchMap具有取消效果。会取消前一个内部observable(你所提供函数的结果)的订阅,然后订阅一个新的observable

	const btn = document.getElementById('btn')
	// 每点击一次,将重新开始,如果换成mergeMap,多次点击会产生多个observable
    fromEvent(btn, 'click').pipe(switchMap(val => interval(1000))).subscribe(res => console.log(res))

startWith

将指定的值作为前置初始值。

	of(1, 2, 3).pipe(startWith(88, 99, 100)).subscribe(res => console.log(res)) // 依次输出88,99,100,1,2,3
	interval(1000).pipe(startWith(88, 99, 100)).subscribe(res => console.log(res)) // 立刻依次输出88,99,100后每间隔1s依次输出0,1,2...

mergeAll

收集并订阅所有的 observablesmergeMap === map + mergeAll

	from([of(1), of(2), of(3)]).pipe(mergeAll(), map(c => c * 10)).subscribe(res => console.log(res)) // 依次输出10,20,30
	from([1, 2, 3]).pipe(map(val => of(val * 10)), mergeAll()).subscribe(res => console.log(res)) // 依次输出10,20,30

scan

类似数组的reduce方法

	from([1, 2, 3]).pipe(scan((pre, cur) => pre + cur, 0)).subscribe(res => console.log(res))	// 依次输出1,3,6
	
	from([{label: '美食', value: 1}, {label: '水果', value: 2}, {label: '动物', value: 3}]).pipe(scan((pre, cur) => {
      pre[cur.label] = cur.value
      return pre
    }, {})).subscribe(res => console.log(res))