服务返回的Observable不会完成

时间:2017-08-29 13:47:16

标签: angular rxjs rxjs5 angular2-http

我有一项使用angular的http服务的服务

@Injectable()
export class MyService {

  constructor(private http: Http) { }

  getThings() {
    return this.http.get('url').map((res) => {
      // massage data here and return massaged data
    });
  }
}

我使用像这样的服务

this.myService.getThings.subscribe(
  things => {},
  err => {},
  () => {
    // never completes...
  });

myService.getThings()完成后,http.get('url')怎么永远不会完成?

如何让myService.getThings()完成?

4 个答案:

答案 0 :(得分:0)

我建议你使用finally运算符,以防当你想要在流发出最后一个值(完成)时执行代码。

例如:

//Inside of a component
this.fooService.getFoos().
finally(()=>console.log("Completed"))
.subscribe(foos => this.foos = foos);

答案 1 :(得分:0)

如果进程中发生某些错误,则不会执行“完成”块。 (最终不起作用)。

在所有步骤中放入一些日志以查找是否发生了一些错误。

答案 2 :(得分:0)

由于github问题中所述的websockets或其他机制,它可能无法完成:https://github.com/angular/angular/issues/7865; 但是这里有两个带有Angular2和Angular4的plunkr,它们都通过HTTP使用了一个模拟json文件,在这两种情况下,observable都能正确完成。

在这两种情况下,我都为您设置了类似的案例:

this.toto().subscribe(
      (result) => {
        console.log('result => ', result);
      },
      (error) => {
        console.log('error => ', error);
      },
      () => {
        console.log('comlete');
      }
    });

  toto() {
    return this.http
    .get('test.json')
    .map((res) => res.json());
  }

Plunkr1:http://plnkr.co/edit/hoIyMHl8abhaG7BYVyns?p=preview

Plunkr2:http://plnkr.co/edit/siVrOIIvT1uWP36LkiOZ?p=preview

答案 3 :(得分:0)

http.get('url')没有“完成”,因为所有这一切都是映射从服务器发送的响应。

有关Observables的一件事需要注意:在订阅之前,他们实际上并没有做任何事情。其次,以下代码:

return this.http.get('url').map((res) => {
  // massage data here and return massaged data
});

返回一个Observable,它只是一个返回数据流的函数。

关于Observables的另一个注意事项是并非所有的Observable都能完成。只有在源完成时,Observable才会完成。在这种情况下,http.get()函数确实完成,因此不需要考虑。

最后,如果Observables触发错误,它们将无法完成。对于http.get()函数,如果服务器产生的响应不是200级响应,则会触发错误。

我建议您更改getThings函数以包含catch运算符:

import {Http, Response} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

return this.http.get('url')
   .map((res) => {
      // massage data here and return massaged data
   })
   .catch((error: Response) => {
      return Observable.throw(error.status);
   });

如果get()请求发生错误,它将返回一个包含服务器状态的Observable。然后,您可以查看状态并查看问题所在。