How to synchronise Angular2 http get?

我是研究僧i 提交于 2019-12-01 02:16:26

You should not try to make http calls behave synchronously. Never a good idea.

Coming to your getAllUser implementation it should return an observable from the function and the calling code should subscribe instead of you creating a subscription inside the method itself.

Something like

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

In you calling code, you should subscribe and do whatever you want.

your service class: /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();
            });
      }

    }

your component: /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
  }

}
Suresh

By looking at the angular source (https://github.com/angular/angular/blob/master/packages/http/src/backends/xhr_backend.ts#L46), it is apparent that the async attribute of the XMLHttpRequest is not getting used. The third parameter of XMLHttpRequest needs to be set to "false" for synchronous requests.

Please find code for your problem Below is component and service file.And Code is Working fine for 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!")
  );
 }

}

Below is service file..

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


  }
}

Another solution would be to implement a priority queue of sort.

From what I understand http requests do not get executed until you add subscribers. Therefore, you can do something like this:

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

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

This assumes that requestPriorityQueue is a service injected into your component. The priority queue would store entries in an array in the following format:

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

You would have to decide how the elements are added to your array. Finally, the following will happen in the background:

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

The processQueue method would do something like this:

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

If you are able to add new dependencies you could try using the following NPM package: async-priority-queue

eDriven_Levar

I looked and I couldn't find any way to make an HTTP call sync instead of async.

So the only way around this: wrap your call in a while loop with a flag. Don't let the code continue until that flag has "continue" value.

Pseudo code as follows:

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

as you see, first callback waiting for a data from request and there you can go on with your logic (or use the third one)

example:

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

How about to use $.ajax(of jQuery) or XMLHttpRequest.

It can use as asynchornize.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!