在角度2应用程序中执行backgroud / seperate线程中的函数

时间:2017-12-07 06:34:31

标签: angular web-worker

我正在开发一个应用程序,我有以下要求。从我的角度应用程序我正在对服务器进行REST调用,这将在服务器上触发一些工作并返回状态为"作业已启动"。之后,我想每10秒检查一次作业状态,为哪台服务器提供返回作业状态的API。

现在我的要求是我需要每10秒调用一次这个作业状态API,但在后台,这意味着用户应该能够在应用程序上执行其他任务。

我将如何实现这一目标?

对某些示例的任何帮助都会非常有用。

2 个答案:

答案 0 :(得分:1)

您可以通过双向解决此问题。

最简单的方式 - setInterval()

由于它只检查作业是否通过http请求完成,因此它不会杀死UI,用户将能够执行其他操作。

setInterval(() => {
   this.http.post(...).subscribe(
      (res) => handleResponse(res);
   );
}, 10000);

Web Worker

对于网络工作者来说,存在很多麻烦,取决于你的项目是如何构建的等等。但是它会用后台线程来解决问题,但是有一个问题。只是为了检查Web工作者需要检查某些数据的http请求吗?如果是,请查看此link,它很好地解释了它是如何工作的。您必须自XHRAngular创建jQuery请求(我不是100%肯定,但网络工作者可能有ajax赢了&#39在那里工作。最大的麻烦就是加载web worker的源代码。您可以stringify Web worker(how to)的源代码,或者只是将其构建为文件并将其链接。这取决于你的项目将如何在生产中建立。

// source code for worker.
let code = function() {
    setInterval(function() {
        makeRequest()
        .then(function(res) {
            // process request. if you want to send message to main thread just use fn below
            // message can be almost everything, but it can not pass any methods.
            // self is simply worker. you don't have to declar self, it's already declared like window in main thread.
            self.postMessage(message)
        })
        .catch(function(err) {
            // process request failure.
        })
    }, 10000)
};

// stringify source code and make it blob as described in link

let worker = new Worker(code);

worker.addEventListener('message', function(workerReponse) {
    // workerReponse is simply `message` which was passed in self.postMessage(message).
})

Source code to blob file

makeRequest方法看起来像answer

答案 1 :(得分:1)

您可以使用带有计时器的RxJS observable,以便您轻松控制计时器。如果你没有在页面卸载时销毁定时器,也会在页面销毁后调用API。在组件文件中,API将每10秒调用一次,直到变量alive为真,我们在destroy上将其设置为false以停止计时器。

Working demo

组件文件

import { Component } from '@angular/core';
import { AppTestService } from './app-test.service';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/takeWhile';
import 'rxjs/add/observable/timer'

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ],
  providers:[ AppTestService ]
})
export class AppComponent  {
  name = 'Angular 5';
  alive = true;

  constructor(private appTest : AppTestService) {
    Observable.timer(0,10000)
    .takeWhile(() => this.alive) // only fires when component is alive
    .subscribe(() => {
      this.appTest.getData().subscribe(data=> {
        console.log(data);
      })
    });
  }

  ngOnDestroy(){
    this.alive = false; // switches your IntervalObservable off
  }
}

服务

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class AppTestService {

  constructor(private http:HttpClient) { }

  getData(){
    return this.http.get('https://jsonplaceholder.typicode.com/users/1');
  }

}