zoukankan      html  css  js  c++  java
  • Angular基础(八) Observable & RxJS

     

     

     

    对于一个应用来说,获取数据的方法可以有很多,比如:Ajax, Websockets, LocalStorage, Indexdb, Service Workers,但是如何整合多种数据源、如何避免BUG、如何提高可维护性、如何提升应用的速度,这些却又是需要解决的问题。MVC是经典的Web应用开发模式,但对于客户端应用却不太适合。针对这点又出现了一些其它的模式,比如MVW(Model-View-Whatever)双向绑定模式、Flux、Observables等。

    Angular1采用双向绑定的方式,但到了Angular4,对于数据结构的选择就非常灵活了,可以根据应用的场景自行决定。

     

    一、Observables and RxJS

    Observables方式属于响应式编程(ReactiveProgramming),数据流是异步传输的,采用Observables方式需要导入RxJS库。接下来通过一个聊天应用的实现了解Observables和RxJS。

    a) 聊天应用整体来说包含三部分,聊天列表、对话框、未读消息。相应地有三个Model、三个service。service维护数据流,数据流传输model,组件订阅数据流并渲染界面。

    userModel包含is,name, avatarSrc三个属性;

    threadModel包含的属性有id, lastMessage, name, avatarSrc;

    messageModel包含的属性有 id, isRead, sentAt, anthor, text, thread.

    b) UserService

    创建的UsersService类需要标记为@Injectable,便于之后的注入。

    import{ Subject, BehaviorSubject } from 'rxjs';

    @Injectable()

    exportclass UsersService {

      currentUser: Subject<User> = newBehaviorSubject<User>(null);

      public setCurrentUser(newUser: User): void {

        this.currentUser.next(newUser);

      }

    }

    currentUser是一个Subject 类型,接收了一个BehaviorSubject对象,Subject是可读可写的流,同时继承了Observable和Observer。一般来说消息发送到流后,如果没有被接收就会丢失,但可使用BehaviorSubject避免这个问题,BehaviorSubject会保存最后一次的值。

    setCurrentUser()会通过Subject.next()将新的值送入流中。

     

    c) MessageService

    MessageService是这个应用的核心,所有的消息流都会经过这个Service。MessageService首先会包含三个“数据管理流”:newMessage发送新消息、messages发送最近消息的数组、update更新messages流。

    update更新messages流时,采用操作流模式(Operation Stream Pattern)。

    interfaceIMessagesOperation extends Function {

      (messages: Message[]): Message[];

    }

    exportclass MessagesService {

      updates: Subject<any> = newSubject<any>();

      constructor() {

        this.messages = this.updates

          .scan((messages: Message[],

                 operation: IMessagesOperation)=> {

                   return operation(messages);

                 },

                initialMessages).

                     .publishReplay(1)

                     .refCount();

    传入updates流中的是方法,这个方法的输入和输出都是message数组,为此定义接口IMessagesOperation,然后使用Subject.scan()。

    流默认是不共享的,一次读取后流中的数据就会消失,但这个应用中不少地方需要多次读取流,比如最近消息,所以使用了publishReplay和refCount方法。publishReplay设置流可在多个订阅者间共享,并可设置对新加入的订阅者的滞后值。

     

     

    学习资料:The Complete Book on Angular by Nate Murray, Felipe Coury, AriLerner , Carlos Taborda

     

  • 相关阅读:
    Easy | LeetCode 154 | 剑指 Offer 11. 旋转数组的最小数字 | 二分法
    Easy | 剑指 Offer 17. 打印从1到最大的n位数 | 大数
    Easy | LeetCode 191 | 剑指 Offer 15. 二进制中1的个数 | 位运算
    Easy | 剑指 Offer 57
    Medium | LeetCode 15. 三数之和 | 双指针法
    jq load()方法实现html 模块化。
    vue 剪切图片上传头像,使用 cropperjs 实现
    vue 的nextTick的理解
    使用nodejs进行开发,concurrently模块,使我们同时执行多个命令。
    cookie生命周期expires 时间过期,但是cookie没有被浏览器清理的问题
  • 原文地址:https://www.cnblogs.com/zhixin9001/p/7446060.html
Copyright © 2011-2022 走看看