Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何暂停并恢复可观察的文档点击?_Javascript_Angular - Fatal编程技术网

Javascript 如何暂停并恢复可观察的文档点击?

Javascript 如何暂停并恢复可观察的文档点击?,javascript,angular,Javascript,Angular,我有一个可观测的,每秒钟都会向控制台发出某些值。我在下面展示了一个例子和一个例子 我的困境是,我需要能够在下一个文档中暂停它,然后在下一个文档中再次单击它(而不是重新启动它)。我在查看switchMap,但不知道如何实现它 export class AppComponent implements OnInit { title = "my-app"; pageClickObservable: Observable<Event> = fromEvent(doc

我有一个可观测的,每秒钟都会向控制台发出某些值。我在下面展示了一个例子和一个例子

我的困境是,我需要能够在下一个文档中暂停它,然后在下一个文档中再次单击它(而不是重新启动它)。我在查看switchMap,但不知道如何实现它

export class AppComponent implements OnInit {
  title = "my-app";
  pageClickObservable: Observable<Event> = fromEvent(document, "click");

  ngOnInit(): void {
    new Observable();

    const watchForClick = () => {
      setTimeout(() => {
        console.log("A");
      }, 1000);
      setTimeout(() => {
        console.log("BB");
        console.log("10");
      }, 2000);
      setTimeout(() => {
        console.log("CCC");
      }, 3000);
      setTimeout(() => {
        console.log("DDDD");
        console.log("20");
      }, 4000);
      setTimeout(() => {
        console.log("EEEEE");
      }, 5000);
      setTimeout(() => {
        console.log("FFFFFF");
        console.log("30");
      }, 6000);
    };

    this.pageClickObservable.pipe().subscribe(() => {
      watchForClick();
    });
  }
}
导出类AppComponent实现OnInit{
title=“我的应用程序”;
pageClickObservable:Observable=fromEvent(文档“点击”);
ngOnInit():void{
新可观测();
const watchForClick=()=>{
设置超时(()=>{
控制台日志(“A”);
}, 1000);
设置超时(()=>{
控制台日志(“BB”);
控制台日志(“10”);
}, 2000);
设置超时(()=>{
控制台日志(“CCC”);
}, 3000);
设置超时(()=>{
控制台日志(“DDDD”);
控制台日志(“20”);
}, 4000);
设置超时(()=>{
控制台日志(“EEEE”);
}, 5000);
设置超时(()=>{
控制台日志(“FFFFFF”);
控制台日志(“30”);
}, 6000);
};
此.pageClickObservable.pipe().subscribe(()=>{
watchForClick();
});
}
}

我所做的是创建一个基于数值属性值延迟值的运算符

delayByProperty.ts 现在你可以做了

from([1,2,3,2,5,2,1]).pipe(
    map(n => {value:n, seconds:Number.parseFloat(n)}),
    delayByProperty('seconds')
)

在处理可观测数据时,我发现少像程序员那样思考,多像管道工一样思考是很有用的。:-)考虑这一点:

function getObservableOfMsgs(click$) {
    //Array of objects that have whatever values you want in them, plus a property of "seconds" that contains the number of seconds you want to delay.
    const objs = [{msg:'1', seconds:1},{msg:'2', seconds:2},{msg:'TWO', seconds:2}];
    // observable we want per click.
    const perClick$ = from(objs).pipe(
        // map each object into an observable that delays, then emits the msg... and combine all of those observables to happen simultaneously.
        mergeMap(({msg, seconds}) => of(msg).pipe(delay(seconds * 1000)))
    );

    return click$.pipe(
        mapTo(perClick$)
    );
}
现在,您将拥有一个可观察对象,它在每次单击时都会发出一系列消息

因此,如果您有一个名为doSomethingWithMessage的函数,该函数将msg作为单个参数,并返回null或希望作为调试消息记录的消息,那么您可以

const unsubscribeFunctionInCaseINeedIt = getObservableOfMsgs(click$).pipe(
    tap(doSomethingWithMessage)
).subscribe(
    (d) => if (d !== null) console.debug(d),
    (e) => console.error(e),
    ()  => console.log('Complete!')
)
然后,在调用返回的函数之前,它将随着事件流的通过而“发生”


from
of
是rxjs的一部分,因此您应该能够
从“rxjs”导入{from,of}
,希望这会自动解决,因为rxjs是rxjs的一部分。同样,您可能还必须从“rxjs/operators”导入{mergeMap,delay,mapTo,tap}或其他内容,但我无法访问StackBlitz来为您确认。

我想您需要这样的内容:

const $myContinuousObs = ...... // This is your observable that keeps emitting
const $isOn = new BehaviourSubject(true); // BehaviorSubject to store the current on/off state

combineLatest([$myContinuousObs, $isOn]).pipe( //combine the two
    filter(res => res[1]), // only continue when $isOn is true
    map(res => res[0]) // return only the myContinuousObs and not the $isOn
).subscribe(console.log) // log the value
要更改
$onOff

$isOn.next(true)
$isOn.next(false)
切换
$onOff

$isOn.pipe(take(1)).subscribe(val => $onOff.next(!val))

您需要将页面单击转换为一些流,以便使用
scan
跟踪交换机的状态,如下所示:

const clickStream$ = fromEvent(document, 'click').pipe(
  scan((isOn, click) => !isOn, true), // on every click, toggle the switch
  startWith(true) // initially emit true
)
然后您就可以
切换地图

clickStream$.pipe(
  switchMap(isOn => isOn ? obs$ : EMPTY)
).subscribe(v => console.log(v, 'got value'))
其中,
obs$
是您想要开始和停止收听的内容。现在,使用
switchMap
的这种方法将重新订阅每个
clickStream$
emission,这取决于感兴趣的可观察对象的性质,可能不是您想要的,但是,
clickStream$
observable的概念与这里使用
过滤器的另一个答案相结合,可能仍然对您有用。请查看以下内容:

import { Component, OnInit } from "@angular/core";
import { fromEvent, Observable } from "rxjs";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit {
  title = "my-app";
  pageClickObservable: Observable<Event> = fromEvent(document, "click");

  pause = false; // creating a variable to track the pause
  ngOnInit(): void {
    new Observable();

    this.pageClickObservable.pipe().subscribe(() => {
      this.pause = !this.pause; // change the pause status - true / false at alternative clicks
    });


 // mimicking observable sending data every second
    setInterval(() => {
      if (!this.pause) {
        // if not pause then execute the complete functions
        console.log("Click");
      } else {
        console.log("Do nothing");
      }
    }, 1000);
  }
}
从“@angular/core”导入{Component,OnInit};
从“rxjs”导入{fromEvent,observeable};
@组成部分({
选择器:“我的应用程序”,
templateUrl:“./app.component.html”,
样式URL:[“/app.component.css”]
})
导出类AppComponent实现OnInit{
title=“我的应用程序”;
pageClickObservable:Observable=fromEvent(文档“点击”);
pause=false;//创建一个变量来跟踪暂停
ngOnInit():void{
新可观测();
此.pageClickObservable.pipe().subscribe(()=>{
this.pause=!this.pause;//在交替单击时更改暂停状态-true/false
});
//模拟每秒发送数据的可观测数据
设置间隔(()=>{
如果(!this.pause){
//如果没有暂停,则执行完整的功能
控制台日志(“单击”);
}否则{
console.log(“不做任何事”);
}
}, 1000);
}
}
这将简单地控制台“单击”和基于单击的“不做任何事情”

例如,每秒都有一个可观察的发送数据,比如说,
setInterval


如果它们共享一个公共变量,例如本例中的
this.pause
,那么您可以轻松地暂停和恢复。

您在我的stackBlitz中测试过这个吗?我不知道如何在itI中实现这一点。我手动将该功能复制到StackOverflow中,因为(出于防火墙原因)我不允许从我的机器将文本粘贴到StackOverflow中,也不允许访问StackBlitz,但让我尝试编辑并进行更多解释……我已经尝试实现了这一点。你的答案有太多漏洞。对于如何实现此解决方案,没有明确的解释。如果这是一个只有精通该技术的人才能理解的解决方案,那么这个人就不会在这里开始提问了。Oof。我不是故意让你失望的。谢谢你的反馈。祝你好运。我重新修改了ti以使用你的解决方案,但我对上一个解决方案感到困惑。我搞不懂最后那部分。看这里。
$myContinuosObs
应该是每秒发射的可见光。问题是您正在更改需求以使其适合您的代码。我不需要console.log时间戳。我需要在1秒发出准确的“A”,在第2秒发出准确的“BB”,在第3秒发出准确的“CCC”,在第4秒发出准确的“DDDD”,在第4秒发出准确的“20”,等等。这表明消息可以完全控制。它们可以是一个简单的conole日志,也可以是一个通知,或者一组指令等等,只要把你拥有的、需要的或想要的东西放在一个可观察的文件中,用它来替换计时器,这样想,想象这个程序在一个机器人的内部,你想让机器人:'控制台日志,他在第二个开始时,在第二个2上对数据发出http请求,在第二个3上处理并向另一个函数发送值,在第二个4上收集结果并发送通知,在第二个5上以消息结束,在第二个6上将自己置于睡眠模式。这些都是在任何情况下都不同的操作。这只是一个例子。N
import { Component, OnInit } from "@angular/core";
import { fromEvent, Observable } from "rxjs";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit {
  title = "my-app";
  pageClickObservable: Observable<Event> = fromEvent(document, "click");

  pause = false; // creating a variable to track the pause
  ngOnInit(): void {
    new Observable();

    this.pageClickObservable.pipe().subscribe(() => {
      this.pause = !this.pause; // change the pause status - true / false at alternative clicks
    });


 // mimicking observable sending data every second
    setInterval(() => {
      if (!this.pause) {
        // if not pause then execute the complete functions
        console.log("Click");
      } else {
        console.log("Do nothing");
      }
    }, 1000);
  }
}