Comment synchroniser Angular2 http get?

je comprends l'utilisation de observable je peux exécuter une méthode lorsque la requête est terminée, mais comment puis-je attendre qu'un http soit terminé et retourner la réponse en utilisant le http ng2?

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

la" valeur " sera nulle quand elle sera retournée car get est async..

20
demandé sur Lynx 242 2015-10-23 08:04:45

8 réponses

vous ne devriez pas essayer de faire en sorte que les appels http se comportent de façon synchrone. Jamais une bonne idée.

pour votre getAllUser mise en oeuvre il devrait retourner un observable de la fonction et le code appelant devrait s'abonner au lieu de vous créer un abonnement à l'intérieur de la méthode elle-même.

quelque Chose comme

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

dans votre code d'appel, vous devez vous abonner et faire ce que vous voulez.

-7
répondu Chandermani 2015-10-23 05:41:40

votre classe de service:/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();
            });
      }

    }

votre composante: /projet/app/composants/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
  }

}
3
répondu Dharan G 2017-07-31 07:41:29

enter image description here en regardant la source angulaire(https://github.com/angular/angular/blob/master/packages/http/src/backends/xhr_backend.ts#L46), il est évident que L'attribut async de XMLHttpRequest n'est pas utilisé. Le troisième paramètre de XMLHttpRequest doit être défini à "false" pour les requêtes synchrones.

2
répondu Suresh 2017-12-11 11:56:40

s'il vous plaît trouver le code pour votre problème Vous trouverez ci-dessous le fichier de composants et de services.Et le Code fonctionne bien pour 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!")
  );
 }

}

ci-dessous est le fichier de service..

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


  }
}
0
répondu stackinfostack 2016-10-23 16:14:56

une autre solution serait de mettre en place une file d'attente prioritaire de sorte.

D'après ce que j'ai compris, les requêtes http ne sont pas exécutées tant que vous n'ajoutez pas d'abonnés. Par conséquent, vous pouvez faire quelque chose comme ceci:

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

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

Cela suppose que requestPriorityQueue est un service injecté dans votre composant. La file d'attente prioritaire stockerait les entrées dans un tableau dans le format suivant:

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

vous devez décider comment les éléments sont ajoutés à votre tableau. Enfin, l' voici ce qui se passera en arrière-plan:

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

processQueue méthode serait de faire quelque chose comme ceci:

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

Si vous êtes en mesure d'ajouter de nouvelles dépendances vous pouvez essayer d'utiliser d'MNP package: asynchrone de priorité de la file d'attente

0
répondu Je Suis Alrick 2018-01-26 14:34:00

j'ai regardé et je n'ai pas pu trouver le moyen de faire une synchronisation D'appel HTTP au lieu d'async.

donc le seul moyen de contourner cela: envelopper votre appel dans une boucle de temps avec un drapeau. Ne laissez pas le code continuer jusqu'à ce que ce drapeau ait la valeur "continue".

Pseudo code comme suit:

let letsContinue = false;

//Call your Async Function
this.myAsyncFunc().subscribe(data => {
   letsContinue = true;
}; 

while (!letsContinue) {
   console.log('... log flooding.. while we wait..a setimeout might be better');
}
0
répondu eDriven_Levar 2018-08-23 05:39:03

comme vous le voyez, premier rappel en attente d'une donnée de request et là vous pouvez continuer avec votre logique (ou utiliser la troisième)

exemple:

.. subscribe( data => { 
              this.value = data; 
              doSomeOperation;
              }, 
              error => console.log(error), 
              () => {console.log("Completed");
                      or do operations here..;
                    }
});
-3
répondu Abdusattar Tursunkul 2016-10-16 14:20:12

Comment utiliser $.ajax (de jQuery) ou XMLHttpRequest.

Il peut utiliser comme asynchornize.

-3
répondu harufumi.abe 2017-06-28 08:03:31