如何使可观察的静态射击不订阅?

时间:2019-06-26 03:04:19

标签: rxjs

我有以下代码=> https://stackblitz.com/edit/angular-3avdpv

this.joystickStart$ = Observable.create(observer => {
  this.joystickManager.on('start',  (evt, nipple) =>  {
    console.log("START")
    observer.next(nipple);
  });
});

this.joystickMove$ = Observable.create(observer => {
  this.joystickManager.on('move',  (evt, nipple) =>  {
    console.log("MOVE")
    this.lastEvent = nipple;
    clearInterval(this.lastInterval);
    this.lastInterval = setInterval(() => {
      observer.next(this.lastEvent);
    }, this.refireFrequency);
    observer.next(nipple);
  });
});

this.joystickRelease$ = Observable.create(observer => {
  this.joystickManager.on('end',  (evt, nipple) =>  {
    console.log("END")
    clearInterval(this.lastInterval);
    observer.next(nipple);
  });
});

我面临的问题是,如果有人订阅了joystickStart $,joystickMove $,joystickEnd $,则可观察内容将被触发。但是如果没有这样做(或仅订阅示例动作,则不会触发开始和结束。

但是,这破坏了我的系统,导致不会清除setInterval。

即使没有订阅者,如何使它正常工作?我应该自动订阅吗?

2 个答案:

答案 0 :(得分:1)

更改为使用主题,并在订阅主题时具有逻辑。

Sub mycode()


       Dim x As Long


       myRange = Workbooks("Book2").Sheets("Sheet1").Range("B1", _ 
       Range("B1").End(xlDown))


       x = WorksheetFunction.Sum(myRange)    '<<does not seem to hold value



      If Workbooks("Book1").Sheets("Sheet1").Range("A1").Value = x Then

         MsgBox ("values equal")

      Else

         MsgBox ("please review values")

      End If



End Sub

答案 1 :(得分:1)

根据您的问题,您似乎想执行以下操作-

操纵杆启动后,立即跟踪操纵杆的运动,直到第一次释放操纵杆为止。如果我的理解是正确的,那么可以使用rxjs运算符[反应性方法]和各种类似的Subject来代替使用setInterval或[命令式方法]:

export class JoystickComponent implements AfterViewInit {
  @ViewChild('joystick') joystick: ElementRef;
  @Input() options: nipplejs.JoystickManagerOptions;

  private lastEvent: nipplejs.JoystickOutputData;
  private refireFrequency: 1000;
  private lastInterval: any;
  private joystickManager: nipplejs.JoystickManager;

  joystickStart$ = new Subject<nipplejs.JoystickOutputData>();
  joystickMove$ = new Subject<nipplejs.JoystickOutputData>();
  joystickRelease$: Subject<nipplejs.JoystickOutputData> = new Subject<nipplejs.JoystickOutputData>();          

  constructor() { }

  ngAfterViewInit() {
    this.create();
  }

  create() {
    this.joystickManager = nipplejs.create({
      zone : this.joystick.nativeElement,
      position: {left: '50%', top: '50%'},
      mode: 'semi'
    });

    this.joystickManager.on('start',  (evt, nipple) =>  {
        this.joystickStart$.next(nipple);
      });    

    this.joystickManager.on('move',  (evt, nipple) =>  { 
        this.joystickMove$.next(nipple);
      });    

    this.joystickManager.on('end',  (evt, nipple) =>  {
        this.joystickRelease$.next(nipple);
      });

    //combine start and move events
    //and do that until you hit first released event
    combineLatest(this.joystickStart$
                      .pipe(tap(_ => console.log(`Joystick Started`))), 
                  this.joystickMove$
                      .pipe(tap(_ => console.log(`Joystick Moved`)))
                 )
    .pipe(
      takeUntil(this.joystickRelease$.pipe(tap(_ => console.log(`Joystick released`)))),
      //If you want to repeat the observable then use repeat operator
      //repeat()
    ).subscribe(([start, move]) => {
      console.log({start}, {move});
    }, () => {}, () => console.log('complete'));    
  }
}

正在工作的堆叠闪电战-https://stackblitz.com/edit/angular-fazjcf?file=src/app/joystick/joystick.component.ts