【问题标题】:How to dispose of in-flight requests如何处理飞行中的请求
【发布时间】:2017-02-10 06:33:04
【问题描述】:

现在脚本的工作方式如下:

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

【问题讨论】:

  • 如果延迟在setTimeout() 中被硬编码,那么我认为您无能为力,因为它超出了您的控制范围。

标签: rxjs


【解决方案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

【讨论】:

    猜你喜欢
    • 2023-03-13
    • 2019-11-14
    • 1970-01-01
    • 2013-09-11
    • 1970-01-01
    • 2018-04-13
    • 2015-09-04
    • 1970-01-01
    • 2012-12-30
    相关资源
    最近更新 更多