2015-10-23 43 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