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

Executing a function in backgroud/seperate thread in angular 2 application

我正在开发一个应用程序,我有以下要求。从我的 angular 应用程序,我正在对服务器进行 REST 调用,这将在服务器上触发一些作业,并且 return 状态为 "Job Started"。之后我想每 10 秒检查一次作业状态,为此服务器提供 API return 作业状态。

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

我该如何实现?

任何有关示例的帮助都会很有帮助。

您可以通过两种方式解决此问题。

最简单的方法 - setInterval().

因为它只是检查作业是否通过 http 请求完成,所以它不会终止 UI 并且用户将能够执行其他操作。

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

网络工作者

对于 web workers 有很多麻烦,这取决于你的项目是如何构建的等等。但是它可以用后台线程来解决问题,但有一个问题。 Web Worker 是否只需要发出 http 请求来检查某些数据?如果是,则查看此 link it's well explained how it works. You will have to create XHR request since Angular and jQuery(I'm not 100% sure, but maybe there is ajax for web workers) won't work there. The biggest trouble would be loading source code of web worker. You can stringify source code of web worker (how to) 或将其构建为文件并 link。这取决于您的项目将如何在生产环境中构建。

// 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 方法可以如下所示

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

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');
  }

}