web-dev-qa-db-fra.com

comment appeler une fonction après la terminaison d'une autre fonction angulaire

J'ai 3 fonctions et je voudrais appeler l'une après l'autre

openTryFunction(){
    // function one
    this.functionOne();
    // after function one
    this.functionTwo();
    // after function two
    this.functionTree(); }
4
Nikolas Soares

Donc, vous avez trois fonctions functionOne, functionTwo et functionThree. Il peut y avoir plusieurs PnC si l'une ou l'autre de ces fonctions est synchrone ou asynchrone.

Généralisons ces scénarios en deux catégories principales:

  1. Tous sont synchrones: si tel est le cas, votre code sera exécuté successivement (de manière synchrone).

  2. Si l'une des fonctions est asynchrone: si c'est le cas, la fonction de nature asynchrone devrait laisser la fonction supposée être appelée après cela, pour savoir qu'elle s'est terminée. Dans ce cas, vous pouvez soit renvoyer une promesse/observable à partir de cette fonction asynchrone. Vous pouvez également lui transmettre une fonction de rappel qui sera appelée une fois l'exécution de la fonction asynchrone terminée.

Deux exemples de ceci seraient:

  1. Disons que toutes ces fonctions sont de nature asynchrone et que toutes ces fonctions renvoient un observable:

Ensuite, vous devriez l'écrire comme ceci:

openTryFunction() {
  this.functionOne()
    .subscribe(
      () => this.functionTwo()
              .subscribe(() => this.functionThree()
                                 .subscribe(() => console.log('Function three terminated')))
    );
}
  1. Si vos functionOne et functionTwo renvoient une promesse, alors:

openTryFunction() {
  this.functionOne().then(() => {
    this.functionTwo().then(() => this.functionThree());
  });
}

Mettre à jour:

Vous pouvez également utiliser async et await pour un code plus propre. Voici un exemple simple mais concret pour le même:

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular';
  users;

  constructor(private http: HttpClient) {}

  ngOnInit() {
    this.getAllData();
  }

  getUsers() {
    return this.http.get('https://jsonplaceholder.typicode.com/users')
      .toPromise();
  }

  getUserPosts(userId) {
    return this.http.get(`https://jsonplaceholder.typicode.com/posts?userId=${userId}`)
      .toPromise();
  }

  getPostComments(postId) {
    return this.http.get(`https://jsonplaceholder.typicode.com/comments?postId=${postId}`)
      .toPromise();
  }

  async getAllData() {
    const users = await this.getUsers();
    const posts = await this.getUserPosts(users[0].id);
    const comments = await this.getPostComments(posts[0].id);

    console.log(users);
    console.log(posts);
    console.log(comments);
  }

}

Voici un StackBlitz pour les mêmes.

J'espère que cela a du sens.

5
SiddAjmera

Vous pouvez utiliser Promise:

functionOne(): Promise<any> {
    return Promise.resolve((() => {
        // code here
        return 'from first'; // return whatever you want not neccessory
    })());
}

functionTwo(): Promise<any> {
    return Promise.resolve((() => {
        // code here
        return 'from second'; // return whatever you want not neccessory
    })());
}

functionThree() {
    // code here
}



this.functionOne().then(data1 => {
    console.log(data1);
    this.functionTwo().then(data2 => {
        console.log(data2);
        this.functionThree();
    });
});
2
Rohit Sharma

Si vos fonctions sont synchrones, ce que vous faites va bien. S'ils sont asynchrones et qu'ils renvoient des promesses, vous pouvez les chaîner de la manière suivante:

fOne()
  .then(() => {
    fTwo()
 } ).then(() => {
  fThree()
});

Sinon, vous pouvez utiliser une attente asynchrone.

async function tasks() {
  await fOne();
 await fTwo();
 await fThree();
}

Soyez sûr de nous essayer d'attraper pour gérer les exceptions.

Si vos fonctions renvoient des observables, concatMap est votre ami.

fOne()
    .concatMap(() => fTwo())
    .concatMap(() => fThree());

Compte tenu de votre dernière fonction Ne renvoie pas une promesse que vous pouvez omettre d’attendre lors du dernier appel en supposant que vous utilisiez async.

2
John Gallego

Regardez cet exemple où chaque fonction retourne une Observable et que la séquence d'exécution est contrôlée par une fonction concat.

export class AppComponent implements OnInit {
  name = 'Angular';
  values = [];

  first(): Observable<string> {
    return of('first');
  }

  second(): Observable<string> {
    return of('second');
  }

  afterSecond(): Observable<string> {
    return of('secondish');
  }

  third(): Observable<string> {
    return of('third');
  }

  ngOnInit() {
    let sequence = concat([
      this.first, 
      this.second, 
      this.afterSecond, 
      this.third]);

    sequence.subscribe(currentFunction => {
      currentFunction().subscribe(value => {
        this.values.Push(value);
      })
    });
  }

}

J'aime la fonction concat car elle crée une Observable des fonctions que nous ajoutons à la liste.

Notez que cet appel sequence.subscribe(currentFunction chaque valeur dans currentFunction sera une fonction, et afin d’en obtenir la valeur réelle, comme il s’agit d’un Observable, vous devez vous y abonner.

Veuillez consulter l'exemple complet ici: https://stackblitz.com/edit/angular-functions-in-sequence?file=src%2Fapp%2Fapp.component.ts

1
hamilton.lima

Si les fonctions renvoient une observable, appelez simplement la fonction suivante danssubscribe. Sinon, renvoyez une promesse de chaque fonction. Ensuite, vous pouvez chaîner les fonctions appelées. 

functionOne() {
    return new Promise((resolve) => {
        //
        // Your function implementation
        //
        // Resolve the promise at the end
        resolve(); 
    });
}

functionTwo() {
    return new Promise((resolve) => {
        //
        // Your function implementation
        //
        // Resolve the promise at the end
        resolve(); 
    });
}

functionThree() {
    return new Promise((resolve) => {
        //
        // Your function implementation
        //
        // Resolve the promise at the end
        resolve(); 
    });
}


openTryFunction(){
    // function one
    this.functionOne().then(() => {
        // after function one
        this.functionTwo().then(() => {
            // after function two
            this.functionTree(); 
        });        
    });
}
1
Faisal

tu peux essayer ça,

openTryFunction(){
this.functionOne().then(()=>{this.functionTwo().then(() => {this.functionTree()})})}

la fonction 3 s'exécutera lorsque 2 sera terminée et 2 si 1 sera terminée.

0
DreamMaker