javascript - 发出第一个值然后忽略计时器内发出的值

标签 javascript angular rxjs observable

这是我的代码:
app.component.ts

notifier$ = new BehaviorSubject<any>({});

notify() {
  this.notifier$.next({});
}

app.component.html

<div (scroll)="notify()"></div>
<child-component [inp]="notifier$ | async" />

问题是,当用户滚动时,notify() 函数被重复调用,而我每次只想调用 notify() 一次 用户开始滚动

我可以通过这种方式完成我想要的:

scrolling = false;
scrollingTimer: NodeJS.Timer;

notify() {
  clearTimeout(this.scrollingTimer);
  if (!this.scrolling) {
    this.notifier$.next({});
  }
  this.scrolling = true;
  this.scrollingTimer = setTimeout(() => (this.scrolling = false), 1000);
}

但我喜欢rxjs来做这件事。但是 debounceTime 与我想要的相反,throttleTimeauditTime 都不是我想要的。有办法做到这一点吗?

最佳答案

您可以像这样构建一个可观察对象:

const scroll$ = fromEvent(document, 'scroll');

const scrollEnd$ = scroll$.pipe(
  switchMapTo(
    timer(1000) // on every scroll, restart a timer
  )
);

const scrollStart$ = scrollEnd$.pipe( // the scroll end event triggers switch to scroll$
  startWith(0), // but start it off
  switchMapTo(
    scroll$.pipe( // then just take the first scroll$ event
      first()
    )
  )
);

scrollStart$.subscribe(v => console.log('scroll start'));

您可以将其概括为运算符:

function firstTimeout(timeout: number) { // welcoming notes on a better name
  return input$ => {
    const inputTimeout$ = input$.pipe(
      switchMapTo(timer(timeout))
    );

    return inputTimeout$.pipe(
      startWith(0),
      switchMapTo(input$.pipe(first()))
    );
  };
}

并像这样使用它:

notifier$.pipe(firstTimeout(1000)).subscribe(v => console.log('took one'));

对于这种情况,一个好主意可能是将它包装在一个易于重用的指令中:

@Directive({
  selector: '[scrollStart]'
})
export class ScrollStartDirective {

  private scrollSource = new Subject();

  @HostListener('scroll', ['$event'])
  private onScroll(event) {
    this.scrollSource.next(event);
  }

  @Output()
  scrollStart = new EventEmitter();

  constructor() {
    this.scrollSource.pipe(firstTimeout(1000)).subscribe(this.scrollStart);
  }
}

然后你可以像这样使用它:

<div (scrollStart)="notify()"></div>

关于javascript - 发出第一个值然后忽略计时器内发出的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57101077/

相关文章:

JavaScript 访问对象的未知属性

javascript - 以给定的 Angular 和长度从 x,y 画一条线

javascript - Webpack:连接文件作为输出的一部分?

javascript - 使用javascript检测ipad或iphone屏幕上的双击

javascript - Ionic 2 和 Firebase 无限滚动

javascript - react 形式 : dynamically add and delete to a type string array in Angular 4

javascript - Rxjs: block 和延迟流?

javascript - 如何处理 Angular 4 浏览器本地存储中的大量数据?

rxjs - RxJS 和 IxJS 的区别?

angular - 无法读取未定义的属性 'next'