even

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

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的时候才会往下执行

 

posted on 2021-09-02 20:36  even_blogs  阅读(89)  评论(0编辑  收藏  举报