现在脚本的工作原理如下:
我按下按钮并在3秒后得到一个值。 如果我按下按钮两次,我会得到两个值,它们之间的延迟等于点击之间的时间。 我的问题是,当我再次单击该按钮时,如何忽略先前的请求。换句话说,每次点击都必须保证 我在3秒钟内得到了下一个值而两者之间没有任何关系。
//foo.js I CAN CHANGE EVERYTHING HERE
import * as bar from './bar';
let oldValue;
bar.subject.subscribe(newValue => {
oldValue = newValue
});
Rx.fromEvent(document, 'click').subscribe(() => {
bar.getValue();
});
//bar.js IT MUST NOT CHANGE
const subject = new Subject();
const getValue = () => {
setTimeout(() => {
subject.next(Math.random());
}, 3000);
};
exports {subject, getValue};
答案 0 :(得分:1)
您描述的模式在Web开发中发生了很多,称为去抖动。
我将仅限于您的具体示例,但请注意,rxjs具有不同的解决方案,具体取决于getValue的功能。例如,如果它是一个后端请求,rxjs有一个AJAX客户端[1]可以从知道如何实际取消以前的AJAX请求的浏览器中使用(请求仍然运行到服务器端结束,但任何结果都不会由浏览器)。
对于此处显示的特定情况,您需要确定具体需要忽略的内容。是否应该忽略过去3秒内最后一次点击之前的点击(并且每3秒只调用一次getValue?在这种情况下
Rx.fromEvent(document, 'click').subscribe(() => bar.getValue());
变为
Rx.fromEvent(document, 'click').debounceTime(3000).subscribe(() => bar.getValue());
如果 bar.getValue()是一个非常耗费资源的函数,您可能希望这样做,只能调用一次。
如果您决定不忽略点击次数,只是忽略3秒内生成的bar.getValue()的先前结果,那么您将替换
bar.subject.subscribe(newValue => oldValue = newValue);
与
bar.subject.debounceTime(3000).subscribe(newValue => oldValue = newValue);
我无法评估您是否使用了某个主题,因为它是您真正需要的,但您可能不需要那个间接而且您可以只使用一个流。如果 getValue 可取消(取消订阅时会停止生成,重新订阅时会再次开始生成值),您可能会将点击链接到使用 switchMap 获取值,它会在完成之前取消任何过时的 getValue 。
[1] https://github.com/Reactive-Extensions/RxJS-DOM/blob/master/doc/operators/ajax.md