2017-08-29 84 views
-1

我有一個使用角度的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()完成?

+0

這可能對你很有趣:https://github.com/angular/angular/issues/7865 –

+0

你解決了這個問題嗎? –

+0

我使用finally方法 – Lev

回答

0

我建議你使用finally運算符來防止當流發出最後一個值(完成)時執行代碼。

例如:

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

如果在這個過程中發生了某種錯誤的「完全的」塊將不被執行。 (最後不起作用)。

在所有步驟中放入一些日誌以查找是否發生了一些錯誤。

0

這是可能的,它不完成,因爲websockets或其他機制,如github問題所述: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

0

的http.get( 'URL')不「完成「,因爲所做的只是映射從服務器發送的響應。

有一點需要注意的是觀察對象:他們實際上並沒有做任何事情,直到他們訂閱。其次,下面的代碼:

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

返回一個Observable,它只是一個返回數據流的函數。

另一件需要注意的問題是,並不是所有的Observables都會天生完成。觀察對象只有完成源代碼才能完成。在這種情況下,http.get()函數會完成,所以這不是您的問題。

最後,如果它們觸發錯誤,Observable將無法完成。對於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); 
    }); 

如果從一開始()請求時發生錯誤,它會返回一個可觀察包含從服務器的狀態。然後,您可以查看狀態並查看問題所在。

+0

根據所需的架構,您對「catch」子句的建議無濟於事。而不是將完整的錯誤對象傳播到'subscribe',你現在只能得到'onError'中的'status'字段。 –