2015-10-23 5 views
16

Я понимаю использование наблюдаемого Я могу выполнить метод, когда запрос будет завершен, но как я могу дождаться завершения HTTP-получения и вернуть ответ, используя в ng2 http?Как синхронизировать Angular2 http get

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 должно возвращать наблюдаемое из функции, а код вызова должен подписываться вместо того, чтобы вы создавали подписку внутри самого метода.

Что-то вроде

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

В вы звоните код, вы должны подписаться и делать все, что вы хотите.

+24

Этот ответ предлагает альтернативную реализацию вопросов, и я ценю ответ. Однако это не отвечает на вопрос. Нет ли способа сделать синхронный запрос HTTP? Я ищу ответ на тот же вопрос, и я в порядке с блокировкой браузера (на самом деле я хочу его), пока не получу ответ. – inki

+2

Этот ответ предполагает не использовать синхронизацию xhr, он никогда не объясняет причину в случае использования вопроса или даже не отвечает на вопрос каким-либо образом, а лишь дает ответ на другой вопрос. –

+0

Посмотрев на угловой источник, кажется, что атрибут async 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; 
    } 


    } 
} 
2

enter image description here Глядя на угловой источник (https://github.com/angular/angular/blob/master/packages/http/src/backends/xhr_backend.ts#L46), то очевидно, что атрибут асинхронной из XMLHttpRequest не привыкают. Третий параметр XMLHttpRequest должен быть установлен на «false» для синхронных запросов.

+1

Запросы синхронизации больше не поддерживаются в большинстве браузеров. Для лучшего опыта пользовательского интерфейса ... – sancelot

-1

Как насчет использования $ .ajax (из jQuery) или XMLHttpRequest.

Его можно использовать как asynchornize.

+0

jQuery нельзя использовать с угловым – Targaryen

+0

Я так не думаю. –

+0

Почему вы так думаете? Некоторые программисты используют jQuery по предпочтению в Angular. –

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

, когда когда-либо наблюдаемые изменения ответа автоматически вызывают ваш метод и обновления с новыми элементами. –

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

Если вы можете добавить новые зависимости вы можете попробовать использовать следующий пакет НПМ: async-priority-queue

Смежные вопросы