【问题标题】:Keep a service running in background in angular保持服务在后台运行
【发布时间】:2019-04-22 17:24:38
【问题描述】:

我创建了一个用于分析的 API,它依赖于客户端每隔几分钟向它发送一个带有会话 ID 的请求(它只保存在一个 var 中,以便每次重新加载页面时都会重置)。我创建了一个角度服务来从客户端发送请求,但我无法让它保持运行并每隔几秒执行一次函数。

我已经在所有组件中导入了服务并在构造函数中声明了它;并且仅在 app 模块中提供它,因此所有组件都可以使用相同的实例

我的所有组件都是由路由器插座在我的应用组件中生成的

服务:

declare var $:any;
export class AnalyticsService {
  sessionID = '';
  uniqueID = '';
  sendStatData() {
    const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
    const sendRequest = () => $.ajax({
      url: 'https://api.com/aah',
      type: 'POST',
      dataType: 'json',
      data: JSON.stringify({
        timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
        sessionID: this.sessionID,
        uniqueID: this.uniqueID,
        address: '',
      })
    });
    const resp = sendRequest()
      .done(response => {
        if (response) {
          console.log(response);
          const data = response;
          if (data.sessionID !== undefined) {
            this.sessionID = data.sessionID;
          }
          if (data.uniqueID !== undefined) {
            localStorage.setItem('uniqueID', data.uniqueID);
            this.uniqueID = data.uniqueID;
          }
          if (data.message === 'uniqueID not found in database') {
            localStorage.removeItem('uniqueID');
            this.uniqueID = '';
            sendRequest();
          }
          delay(30000);
          sendRequest();
        }
      });
  }
  start() {
    if (localStorage.getItem('uniqueID') !== null){
      this.uniqueID = localStorage.getItem('uniqueID');
    }
    this.sendStatData();
  }
}

app.module.ts:

.
.
import {AnalyticsService} from './analytics.service';
.
.
@NgModule({
  .
  .
  .
  providers: [AnalyticsService],
  .
  .
})

app.component.ts:

import {Component, OnInit} from '@angular/core';
import {AnalyticsService} from './analytics.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  constructor(private service: AnalyticsService) { }
  ngOnInit(): void {
    this.service.start();
  }
}

social.component.ts(其他在服务实现方面相同):

import { Component, OnInit } from '@angular/core';
import {AnalyticsService} from '../analytics.service';
declare var $:any;
@Component({
  selector: 'app-skills',
  templateUrl: './skills.component.html',
  styleUrls: ['./skills.component.css']
})
export class SkillsComponent implements OnInit {
  constructor(private service: AnalyticsService) { }

  ngOnInit() {
  }

}

期望:

服务每 30 秒向我的 API 发送一个请求,其中包含存储的会话 ID

实际:

该服务仅在网站重新加载时发送一次请求,而与正在查看的组件无关

【问题讨论】:

  • 你好,首先你为什么不使用 Angular HttpClient ?您将能够结合 RXJS 计时器和您的服务调用。有类似的东西:const timer$ = timer(0, 30000); this.cache$ = timer$.pipe( switchMap(_ => this.sendRequest()), shareReplay(1) );

标签: jquery angular angular-services


【解决方案1】:

正如@Gilsdav 所建议的,这应该切换到某种外部计时机制,而不是递归地延迟响应内部。还赞同使用 Angulars 的内置 HttpClient 而不是使用 jquery ajax 调用的意见(注意:最后我听说如果可以避免的话,通常建议不要将 jquery 与 Angular 一起使用)。

在最基本的情况下,对于任何重复的内容,您都可以通过以下方式摆脱困境:

constructor(private http: HttpClient){}

ngOnInit(): void {
  setInterval(() => { this.sendRequest(); }, 30000);
}

sendRequest(): void {
  this.http.post('https://api.com/aah', data)
    .subscribe((res) => {
      console.log(res);
    });
}

但您可能希望使用与您现有的更集成的东西(使用 rxjs 等,如已经建议的那样)。

【讨论】:

    猜你喜欢
    • 2014-06-26
    • 1970-01-01
    • 1970-01-01
    • 2018-12-15
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 2020-05-01
    • 2012-08-14
    相关资源
    最近更新 更多