通过Observable解决搜索框问题
栏目: JavaScript · 发布时间: 7年前
内容简介:观察者模式也叫发布订阅模式. 最经典的用法就是在事件监听里面.大致提一下,网上对观察者模式的解释有很多. Observable就是基于观察者模式实现的基本特征:
观察者模式也叫发布订阅模式. 最经典的用法就是在事件监听里面.
<button onClick = "handle()">确认</button>
handle方法订阅了onClick事件,当用户点击(发布)onClick, handle方法触发
复制代码
大致提一下,网上对观察者模式的解释有很多. Observable就是基于观察者模式实现的
Observable方法的定义
基本特征:
- 是一个函数
- 接受一个 Observer 对象
- 返回一个具有 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个问题
- 不能在用户输入每个字符的时候就触发搜索。
- 服务器的异步返回时间不一致,先搜索的字符可能数据可能返回比后搜索的慢
代码如下
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>
);
}
}
复制代码
- 通过 debounceTime 延迟返回结果
- 通过 switchMap 丢弃上一个未及时返回的结果
- 而且整个代码显得如此短小精悍
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
SOA & Web 2.0 -- 新商业语言
(美)Sandy Carter / 袁月杨、麻丽莉 / 清华大学出版社 / 2007 / 29.80元
在《SOA&Web 2.0:新商业语言》中,Sandy Calter示范了将企业解构为“组件化”业务模式的方法,然后用相互连接的、可重复的并且能快速、轻松、经济地适应各种变化的IT服务来支持该模式。这些技术将帮助IT专家和业务经理达到崭新的运营水平,以开展着眼于市场的创新,这才是最重要的。总而言之,企业必须实现灵活应对。直到最近,技术都一直阻碍着这些目标的实现。正是由于面向服务架构(SOA)、We......一起来看看 《SOA & Web 2.0 -- 新商业语言》 这本书的介绍吧!
JS 压缩/解压工具
在线压缩/解压 JS 代码
RGB CMYK 转换工具
RGB CMYK 互转工具