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(); }
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:
Tous sont synchrones: si tel est le cas, votre code sera exécuté successivement (de manière synchrone).
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:
Ensuite, vous devriez l'écrire comme ceci:
openTryFunction() {
this.functionOne()
.subscribe(
() => this.functionTwo()
.subscribe(() => this.functionThree()
.subscribe(() => console.log('Function three terminated')))
);
}
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.
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();
});
});
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.
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
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();
});
});
}
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.