如何处理飞行中的请求

时间:2017-01-22 04:19:33

标签: rxjs

现在脚本的工作原理如下:

我按下按钮并在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};

1 个答案:

答案 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