1.用法:const observer = eventTarget.when(eventType);
- eventTarget: 任何继承自 EventTarget 的对象,如 HTMLElement、Window、XMLHttpRequest、Web Socket 等。
- eventType: 字符串,表示要监听的事件类型(如 'click'、'load'、'input')
-
observer: Observer实例对象,包含方法如图:
observer实例
2.实例方法
-
reduce:
reduce方法的调用需结合take(n)方法使用,事件触发n次后,返回结果打印日志,之后事件不会再调用了
const ob = document.body.when('click');
const r = await ob.take(3).reduce(function (total, delta, t) {
console.log('total: ', total);
console.log('点击次数:', t);
return {
totalDx: total.totalDx + delta.clientX,
totalDy: total.totalDy + delta.clientY
}
}, { totalDx: 0, totalDy: 0 })
console.log('触发三次后结果', r);
image.png
-
toArray:
toArray方法的调用结合take(n)方法使用,事件触发n次后,收集n次事件后的结果并返回,之后事件不会再调用了
async function handleClick() {
const ob = document.when('click');
const r = await ob.take(3).map((event, t) => {
console.log('点击次数:', t);
return { x: event.clientX, y: event.clientY }
}).toArray()
console.log(r);
}
handleClick()
image.png
-
forEach:
forEach方法的调用结合take(n)方法使用,事件触发n次后不再触发,forEach是否有返回结果看其是否调用then方法返回结果,forEach的回调方法没有返回值
async function handleClick() {
let times = 0
const el = document.getElementById('list');
const r = await el.when('click')
.filter((event) => event.target.tagName === 'LI')
.take(4)
.forEach((event, t) => {
console.log('点击次数:', t, event.target.textContent);
// 这里可以执行副作用操作,如修改UI
event.target.style.backgroundColor = 'lightblue';
// 2秒后恢复颜色
setTimeout(() => {
event.target.style.backgroundColor = '';
}, 2000);
times = t + 1
return t // 无效返回,为了演示保留
}).then(res => {
console.log(res, '--res');
return times
})
console.log('总共点击次数:', r);
}
handleClick()
image.png
image.png
-
switchMap: 在
switchMap方法里可获取异步数据并返回,在subscribe回调中订阅到返回值,如下图:
function handleInput() {
const ob = input.when('input');
ob.switchMap(event => {
const val = event.target.value;
console.log('val: ', val);
return fetch(`https://jsonplaceholder2.typicode.com/posts/${val}`)
.then(response => {
if (response.status !== 200) {
// throw new Error('请求失败') // subscribe的error回调捕捉
// return Promise.reject(('请求失败')) // subscribe的error回调捕捉
return Promise.resolve({ code: 404, data: null, msg: '请求失败' }) //subscribe的next回调捕捉
}
return response.json()
})
})
.catch(err => {
console.log('err1: ', err);
return { fallback: 'error data' }
})
.finally((s) => {
console.log(s, 'finally');
})
.subscribe({
next(value) {
console.log('订阅结果是', value);
},
error(err) {
console.log('err2: ', err);
},
});
}
handleInput()
image.png
这里可结合
catch、finally方法使用,注意顺序,catch、finally需在subscribe前调用。当接口返回Promise.reject值或抛出异常时,会被catch、finally方法依次捕捉,同时subscribe的error回调也会触发,若error回调省略则控制台会报错,如下图:
image.png
switchMap的适用场景如搜索框输入提示、表单提交按钮的防重复点击、标签页切换加载数据,比如在input中快速输入值,只有最后一次输入会得到响应结果,前面的输入会发起请求不会得到响应结果,如下图:
function handleInput() {
const ob = input.when('input');
ob.flatMap(event => {
const val = event.target.value;
console.log('val: ', val);
return fetch(`https://jsonplaceholder.typicode.com/posts/${val}`)
.then(response => response.json())
})
.subscribe({
next(value) {
console.log('订阅结果是', value);
},
error(err) {
console.log('err: ', err);
},
});
}
handleInput()
image.png
image.png
-
flatMap: 和
switchMap类似,适用场景通知、日志记录、需要处理所有请求结果。switchMap是“喜新厌旧” ,新任务一来,立刻放弃旧任务,只处理最新的。flatMap是来一个任务就处理一个,所有任务立即执行,先发先出,但不保证按顺序返回结果
function handleInput() {
const ob = input.when('input');
ob.switchMap(event => {
const val = event.target.value;
console.log('val: ', val);
return fetch(`https://jsonplaceholder.typicode.com/posts/${val}`)
.then(response => response.json())
})
.subscribe({
next(value) {
console.log('订阅结果是', value);
},
error(err) {
console.log('err: ', err);
},
});
}
handleInput()
image.png
image.png
-
inspect:
inspect方法在开发调试、性能监控和系统维护方面有着独特的价值,他像给数据流安装了一个透明的观察窗口,能够看到数据在每个阶段的形态,而不会影响数据的流动。这在复杂的异步处理流程中特别有价值
function handleInput() {
const ob = input.when('input');
ob.map(event => event.target.value)
.inspect(rawValue => console.log('原始输入:', rawValue))
.filter(value => value.length > 1)
.inspect(filteredValue => console.log('过滤后输入:', filteredValue))
.switchMap(searchTerm => fetch(`https://jsonplaceholder.typicode.com/posts/${searchTerm}`))
.inspect(response => console.log('API响应:', response.status))
.switchMap(response => response.json())
.inspect(data => {
console.log('解析后的数据:', data);
})
.subscribe(results => {
console.log('最终结果:', results);
});
}
handleInput()
image.png









网友评论