remove page from change angular2 javascript angular typescript angular2-http

javascript - page - ¿Cómo sincronizar Angular2 con http?



router events subscribe angular 4 (8)

Comprendo que puedo usar observable. Puedo ejecutar un método cuando se completa la solicitud, pero ¿cómo puedo esperar hasta que se complete un http get y devolver la respuesta usando ng2 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; }

el "valor" será nulo cuando se devuelva porque get es async ..


¿Qué hay de usar $ .ajax (de jQuery) o XMLHttpRequest?

Se puede utilizar como asíncrono.


Busqué y no pude encontrar ninguna manera de hacer una sincronización de llamadas HTTP en lugar de asíncrono.

Así que la única forma de evitar esto: envuelva su llamada en un bucle while con una bandera. No permita que el código continúe hasta que la bandera tenga un valor de "continuar".

Pseudo código de la siguiente manera:

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


Encuentre el código para su problema A continuación se encuentra el archivo de componentes y servicios. Y el código funciona bien para sincronizar

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

A continuación se muestra el archivo de servicio ...

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


No debe intentar que las llamadas http se comporten de forma síncrona. Nunca una buena idea.

Al llegar a la implementación de getAllUser , debe devolver un observable desde la función y el código de llamada debe suscribirse en lugar de que usted cree una suscripción dentro del método en sí.

Algo como

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

En tu código de llamada, debes suscribirte y hacer lo que quieras.


Otra solución sería implementar una cola de prioridad de ordenación.

Por lo que entiendo, las solicitudes http no se ejecutan hasta que agregue suscriptores. Por lo tanto, puedes hacer algo como esto:

Observable<Response> observable = http.get("/api/path", new RequestOptions({})); requestPriorityQueue.add(HttpPriorityQueue.PRIORITY_HIGHEST, observable, successResponse => { /* Handle code */ }, errorResponse => { /* Handle error */ });

Esto supone que requestPriorityQueue es un servicio inyectado en su componente. La cola de prioridad almacenaría las entradas en una matriz en el siguiente formato:

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

Tendrías que decidir cómo se agregarán los elementos a tu matriz. Finalmente, lo siguiente pasará en el fondo:

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

El método processQueue haría algo como esto:

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 puede agregar nuevas dependencias, puede intentar usar el siguiente paquete NPM: async-priority-queue


como ve, primero la devolución de llamada en espera de un dato de solicitud y allí puede continuar con su lógica (o usar la tercera)

ejemplo:

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


su clase de servicio: /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(); }); } }

su componente: /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 } }