之前我有对节流和防抖进行了简单的学习,尤其是在Angular中防抖对和节流的学习中,有了解到RxJs中的switchMap操作符,它是一个防抖和节流很好的辅助。
Rxjs和防抖,节流的知识点复习:
- RxJS-----RxJS简介
- 防抖和节流-------防抖和节流的简介
- Angular中的防抖和节流--------Angular中如何实现防抖和节流
接着,让我们进入正题:switchMap操作符的学习:
switchMap操作符常用于处理和转换数据流。它的特点是在源 observable 发出新值时,会取消并切换到新的 inner observable(内部可观察对象),因此非常适合处理只关心最新数据的场景。
switchMap
是做什么的?
switchMap是一个映射操作符,它接收源 observable 发出的值,并基于该值返回一个新的 observable。与其它映射操作符不同的是,switchMap在源 observable 发出新值时,会取消当前正在执行的内部 observable,订阅新的 observable。
这使得 switchMap 在以下情况中非常有用:
- 当你只关心最新的请求或结果。
- 在请求中,如果新的请求到达时取消掉当前的请求(比如搜索建议、实时数据过滤等)。
switchMap
的工作流程:
- 源 observable 发出一个值。
- switchMap将源值映射到一个新的 observable,并订阅它。
- 如果源 observable 再次发出新的值,switchMap会取消当前订阅的 inner observable,并订阅新的 inner observable。
关键点:
- 切换到新的 observable。
- 取消当前正在进行的 inner observable。
- 适用于你只关心最新发出的值,并且需要丢弃之前的值(比如搜索框、实时数据等)。
使用场景:
- 搜索输入框:用户输入时,取消当前的 HTTP 请求,发起新的请求获取最新的数据。
- 实时数据:例如实时股票数据、天气更新等,只关心最新的值,不需要处理旧的值。
总结:
switchMap 主要用来处理连续的、异步的数据流,确保只处理最新的请求或事件,避免了不必要的请求或操作。在需要取消上一个操作并只关注最后一次结果时,switchMap 是一个非常有用的工具。
完整示例:
下面是一个使用 switchMap 的简单示例,假设我们在实现一个搜索功能,每次输入框内容变化时发出一个请求。
import { of, fromEvent } from 'rxjs';
import { switchMap, debounceTime, map, distinctUntilChanged } from 'rxjs/operators';
// 模拟 HTTP 请求
const simulatedHttpRequest = (query) => {
console.log(`发起请求:${query}`);
return of(`查询结果: ${query}`);
};
// 获取搜索框输入事件
const searchInput = fromEvent(document.getElementById('searchBox'), 'input');
searchInput.pipe(
debounceTime(300), // 等待 300 毫秒,防止用户快速输入时发起多个请求
map(event => event.target.value), // 获取输入框的值
distinctUntilChanged(), // 如果输入值没有变化,就不发起新的请求
switchMap(query => simulatedHttpRequest(query)) // 取消上一个请求,发起新的请求
)
.subscribe(response => {
console.log(response); // 输出查询结果
});
解释代码:
debounceTime(300)
:当用户停止输入 300 毫秒后才会触发下一步操作,避免每次输入都触发请求。distinctUntilChanged()
:只有在输入值发生变化时,才会继续触发请求,防止重复请求相同的内容。switchMap
:每次输入框的值发生变化时,都会取消当前的请求并根据最新的输入发起新的请求。
请求发起的时机:
- 用户输入:用户开始输入时,fromEvent会捕获到输入框的事件。
- 防抖操作:通过debounceTime(300),只有在用户停止输入超过 300 毫秒后,才会触发下一步。
- 发起请求:当防抖完成后,switchMap会根据当前输入值发起新的请求,且会取消之前的请求。
关键点:
- 防止过多请求:通过 debounceTime来确保请求不会频繁发出,避免性能问题。
- 只处理最新的请求:switchMap保证了在输入变化时,总是发起基于最新输入的请求,而取消所有之前的请求。这样就能确保始终得到最新的数据。
总结:
- switchMap会在源 observable 发出新值时触发。
- 每当输入框的值发生变化时,switchMap会取消上一个请求并发起新的请求。
- 防抖操作符(如 debounceTime)可以避免每次输入都触发请求,只在用户停止输入后才发起请求。