通过Observable解决搜索框问题

栏目: JavaScript · 发布时间: 7年前

内容简介:观察者模式也叫发布订阅模式. 最经典的用法就是在事件监听里面.大致提一下,网上对观察者模式的解释有很多. Observable就是基于观察者模式实现的基本特征:

观察者模式也叫发布订阅模式. 最经典的用法就是在事件监听里面.

<button onClick = "handle()">确认</button>
    handle方法订阅了onClick事件,当用户点击(发布)onClick, handle方法触发
复制代码

大致提一下,网上对观察者模式的解释有很多. Observable就是基于观察者模式实现的

Observable方法的定义

基本特征:

  1. 是一个函数
  2. 接受一个 Observer 对象
  3. 返回一个具有 unsubscribe 功能的函数或者对象
let ob = new Observable(obser => {
    // 这个函数是“发布”
    obser.next()
})
// 订阅了console.log(12)动作
ob.subscribe({
    next(){console.log(12)}
})
注:只有subscribe方法执行了才会执行"发布"函数
复制代码

core-js 中已对 observable 做了扩展,通过 import "core-js/es7/observable" 可以使用 Observable

实现Observable方法

便于理解,还是简单的实现一个 Observable 吧,代码如下

class SubscriptionObserver {
    constructor(ob, debounceTime){
        this.ob = ob || {};
        this.debounceTime = debounceTime;
        this.unSub = false;
        this.timeout = null;
    }
    next(value){
        if (!this.unSub && this.ob.next){
            clearTimeout(this.timeout)
            this.timeout = setTimeout(() => {
                !this.unSub  &&this.ob.next(value);
                this.timeout = null;
            }, this.debounceTime)
        } else {
            this.ob.next(value);
        }
    }
    error(){
        if (!this.unSub && this.ob.error){
            this.ob.error();
        }
    }
    complete(){
        if (!this.unSub && this.complete){
            this.ob.complete();
        }
    }
    unsubcribe(){
        this.unSub = true;
    }
}

class Observable {
    constructor(SubscriptionOb) {
        this.SubscriptionOb = SubscriptionOb;
    }
    subscribe(ob){
        this.subOb = new SubscriptionObserver(ob, this.timeout);
        return this.SubscriptionOb(this.subOb);
    }
    unsubcribe(){
        this.subOb.unsubcribe()
        return this;
    }
    debounceTime(timeout){
        this.timeout = timeout;
        return this;
    }
}

复制代码

主要增加了 debounceTime 功能, 在 debounceTime 在lazy时间内只会执行最后一次 next 方法

搜索框的应用

搜索框的搜索主要是要解决2个问题

  1. 不能在用户输入每个字符的时候就触发搜索。
  2. 服务器的异步返回时间不一致,先搜索的字符可能数据可能返回比后搜索的慢

代码如下

export default class Tudos extends React.Component {
    state = {
        text:""
    }
    // 搜索关键字接口
    searchKeyWords(text){
        return new Promise((resolve) => {
            setTimeout(() => {
                let list = [{...}...]
                resolve(list)
            }, 2000)
        })
    }
    handleInput(dom) {
        let oba = new Observable(ob => {
            dom.oninput = e => {
                ob.next(e.target.value)
            }
        }).debounceTime(500).subscribe({
            next(value){getList(value)}
        })

    }
    render() {
        return (<div>
            <input ref = {dom => dom && this.handleInput(dom)}/>
        </div>)
    }
}

复制代码

总会在用户输入完500毫秒后执行 next 函数。这个上述代码已实现. 第二个问题还未解决!

引入RxJS

安装

npm i @reactivex/rxjs --save;
复制代码

引入

import * as Rx from "@reactivex/rxjs";
复制代码

RxJS当做是用来处理事件的 Lodash .像这种复杂的事件处理第一个就是想到使用 RxJS

具体的使用可以参考以下官方文档

代码如下

export default class SimpleSortableList extends Component {
    componentDidMount() {
        
    }
    // 搜索关键字接口
    searchKeyWords(text){
        return new Promise((resolve) => {
            setTimeout(() => {
                let list = [{...}...]
                resolve(list)
            }, 2000)
        })
    }
    handleInput(button){
        Rx.Observable.fromEvent(button, 'input')
        .debounceTime(500)
        .switchMap(e => {
            return Rx.Observable.create(ob => {
                this.searchKeyWords(e.target.value).then(res => {
                    ob.next(list)
                })
            });
        })
        .subscribe(text => console.log(text))
    }
    render() {
        return (
            <div className={prefix}>
                <input ref = { dom => dom && this.handleInput(dom)} />
            </div>
        );
    }
}
复制代码
  1. 通过 debounceTime 延迟返回结果
  2. 通过 switchMap 丢弃上一个未及时返回的结果
  3. 而且整个代码显得如此短小精悍

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Host Your Web Site In The Cloud

Host Your Web Site In The Cloud

Jeff Barr / SitePoint / 2010-9-28 / USD 39.95

Host Your Web Site On The Cloud is the OFFICIAL step-by-step guide to this revolutionary approach to hosting and managing your websites and applications, authored by Amazon's very own Jeffrey Barr. "H......一起来看看 《Host Your Web Site In The Cloud》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

URL 编码/解码
URL 编码/解码

URL 编码/解码