2015-10-23 69 views
16

我明白使用observable我可以在請求完成時執行一個方法,但我如何等待一個http get完成並返回在ng2 http中使用的響應?如何同步Angular2 http獲得

getAllUser(): Array<UserDTO> { 
    this.value = new Array<UserDTO>(); 
    this.http.get("MY_URL") 
        .map(res => res.json()) 
        .subscribe(
         data => this.value = data, 
         err => console.log(err), 
         () => console.log("Completed") 
    ); 

    return this.value; 
} 

「價值」的意志爲空時,其返回,因爲得到的是異步..

+1

你可以使用'$ q'服務或在ajax成功回調中執行你的函數 – Vineet

+0

@Vineet Angular 2不使用'$ q' – Targaryen

回答

-6

您不應該嘗試使http調用的行爲同步。從來不是一個好主意。

來到你的getAllUser實現它應該從函數返回一個observable,並且調用代碼應該訂閱而不是在方法本身內創建一個訂閱。

喜歡的東西

getAllUser(): Observable<UserDTO> { 
     return this.http.get("MY_URL") 
         .map(res => res.json()); 
} 

在你調用代碼,您應該訂閱,做任何你想要的。

+24

這個回答爲這些問題提供了一個替代實現,我很欣賞這個回答。但是,這並沒有回答這個問題。有沒有辦法讓一個同步http請求?我正在尋找同一個問題的答案,並且我確定阻止瀏覽器(實際上我希望它),直到我得到響應。 – inki

+2

這個答案只是建議不要使用同步xhr,它不會解釋問題用例中的原因,甚至不會以任何方式回答問題,而只是回答另一個問題。 –

+0

通過查看角源,似乎XMLHttpRequest的異步屬性沒有得到使用。 – Suresh

-1

JavaScript是單線程的,並作出同步HTTP請求將阻止整個瀏覽器同時等待響應。 請考慮這個不同的體系結構。

+23

這不是對這個問題的回答,只是作爲應該在評論中的問題。 –

-3

正如你看到的,第一個回調等待請求和 有一個數據,你可以繼續你的邏輯(或使用第三個)

例如:

.. subscribe(data => { 
       this.value = data; 
       doSomeOperation; 
       }, 
       error => console.log(error), 
      () => {console.log("Completed"); 
         or do operations here..; 
        } 
}); 
+0

您可以在「在此處執行操作...」的地方輸入其他訂閱請求嗎? – GSeriousB

0

請查找代碼你的問題 下面是組件和服務file.And代碼是synchornize

import { Component, OnInit } from '@angular/core'; 
import { LoginserviceService } from '../loginservice.service'; 

@Component({ 
    selector: 'app-login', 
    templateUrl: './login.component.html', 
    styleUrls: ['./login.component.css'] 
}) 
export class LoginComponent implements OnInit { 
    model:any={}; 
    constructor(private service : LoginserviceService) { 
} 

ngOnInit() { 

} 
save() { 
    this.service.callService(this.model.userName,this.model.passWord). 
    subscribe(
     success => { 
     if(success) { 
      console.log("login Successfully done---------------------------- -"); 
      this.model.success = "Login Successfully done"; 
    }}, 
    error => console.log("login did not work!") 
); 
} 

} 

下面做工精細的服務文件..

import { Injectable } from '@angular/core'; 
import { Http } from '@angular/http'; 
import { UserData } from './UserData'; 
import 'rxjs/add/operator/map' 
import 'rxjs/add/operator/toPromise' 
import {Observable} from 'rxjs/Rx' 

@Injectable() 
    export class LoginserviceService { 
    userData = new UserData('',''); 
    constructor(private http:Http) { } 

    callService(username:string,passwrod:string):Observable<boolean> { 
    var flag : boolean;  
    return (this.http.get('http://localhost:4200/data.json'). 
     map(response => response.json())). 
     map(data => { 
      this.userData = data; 
      return this.loginAuthentication(username,passwrod); 
     }); 
     } 

    loginAuthentication(username:string,passwrod:string):boolean{ 
    if(username==this.userData.username && passwrod==this.userData.password){ 
     console.log("Authentication successfully") 
     return true; 
    }else{ 
    return false; 
    } 


    } 
} 
-1

如何使用$ .ajax(jQuery)或XMLHttpRequest。

它可以作爲asynchornize使用。

+0

jQuery不應該和Angular一起使用 – Targaryen

+0

我不這麼認爲。 –

+0

你爲什麼這麼認爲? 某些程序員在Angular中偏好使用jQuery。 –

2

服務類:/project/app/services/sampleservice.ts

@Injectable() 
    export class SampleService { 

     constructor(private http: Http) { 
     } 

     private createAuthorizationHeader() { 
     return new Headers({'Authorization': 'Basic ZXBossffDFC++=='}); 
     } 


     getAll(): Observable<any[]> { 
     const url=''; 
     const active = 'status/active'; 
     const header = { headers: this.createAuthorizationHeader() }; 
     return this.http.get(url + active, header) 
      .map(
      res => { 
       return res.json(); 
      }); 
     } 

    } 

您的組件:/project/app/components/samplecomponent.ts

export class SampleComponent implements OnInit { 


    constructor(private sampleservice: SampleService) { 
    } 

    ngOnInit() { 
    this.dataset(); 
    } 

    dataset(){ 
    this.sampleservice.getAll().subscribe(
     (res) => { 
     // map Your response with model class 
     // do Stuff Here or create method 
     this.create(res); 
     }, 
     (err) => { } 
    ); 
    } 
    create(data){ 
    // do Your Stuff Here 
    } 

} 
+0

當響應發生變化時,observable會自動調用您的方法和更新與新的元素。 –

0

另一種解決方案是實施排序的優先隊列。

從我理解的http請求不會得到執行,直到您添加訂閱者。因此,你可以做這樣的事情:

Observable<Response> observable = http.get("/api/path", new RequestOptions({})); 

requestPriorityQueue.add(HttpPriorityQueue.PRIORITY_HIGHEST, observable, 
       successResponse => { /* Handle code */ }, 
       errorResponse => { /* Handle error */ }); 

這假定requestPriorityQueue注入到你的組件服務。優先級隊列將在存儲陣列中的條目格式如下:

Array<{ 
    observable: Observable<Response>, 
    successCallback: Function, 
    errorCallback: Function 
}> 

你將不得不決定元素如何添加到您的陣列。

// HttpPriorityQueue#processQueue() called at a set interval to automatically process queue entries 

processQueue方法會做這樣的事情:最後,下面會發生在後臺

protected processQueue() { 
    if (this.queueIsBusy()) { 
     return; 
    } 

    let entry: {} = getNextEntry(); 
    let observable: Observable<Response> = entry.observable; 

    this.setQueueToBusy(); // Sets queue to busy and triggers an internal request timeout counter. 
    observable.subscribe() 
     .map(response => { 
      this.setQueueToReady(); 
      entry.successCallback(response); 
     }) 
     .catch(error => { 
      this.setQueueToReady(); 
      entry.errorCallback(error); 
     }); 
} 

如果能夠增加新的依賴,你可以嘗試使用以下NPM包: async-priority-queue