2017-08-04 6 views
3

Nouvelle à angulaire et des promesses, mais je me suis rendu compte que je l'ai fait beaucoup:propre écriture fermeture d'achèvement de la promesse

this.myService.createFoo(data).subscribe(
    (result: any) => { 
    resolve({success: true, data: result}); 
    }, 
    err => { 
    resolve({success: false, message: err}); 
    }); 

this.myService.updateFoo(data).subscribe(
    (result: any) => { 
    resolve({success: true, data: result}); 
    }, 
    err => { 
    resolve({success: false, message: err}); 
    }); 

Comment puis-je réécrire la fermeture d'achèvement pour ma méthode abonner afin que je n » t répète le code comme ça? Merci!

+0

Vous pourriez essayer d'utiliser 'async' et' await' mais je ne suis pas sûr de la facilité avec laquelle vous vous glisserez dans ce que vous faites (pas très familier avec l'angulaire ou l'abonnement) https: // developer.mozilla.org/en-US/docs/Web/JavaScript/Re ference/Statements/async_function –

+1

Comment 'resolve' et' reject' sont-ils définis? Est-ce que ceux qui viennent du constructeur 'Promise', comme' return new Promise ((résoudre, rejeter) => {...}) ', ou ailleurs? Pourrait aider si vous avez posté un échantillon de code légèrement plus inclusif. –

+0

Oui, c'est comme la nouvelle promesse normale ... comme vous l'avez dit. – 7ball

Répondre

2

Une approche serait d'extraire vos callbacks en fonctions génériques et il suffit de passer celles-ci:

const successHandler = (data: any) => resolve({success: true, data }); 
const errorHandler = (message) => resolve({success: false, message }); 

this.myService.createFoo(data).subscribe(successHandler, errorHandler); 
this.myService.updateFoo(data).subscribe(successHandler, errorHandler); 

Si vous souhaitez définir ces en dehors du champ d'application de la Promise (que je suppose que le code affiché est à l'intérieur de), vous pouvez curry les gestionnaires:

certains-util-library.js

const handlers = resolve => ({ 
    success: (data: any) => resolve({success: true, data }), 
    error: (message) => resolve({success: false, message }) 
}); 
export { handlers }; 

otherfile.js

import { handlers } from './some-util-library.js'; 
... other code 
const { success, error } = handlers(resolve); 
this.myService.createFoo(data).subscribe(success, error); 
this.myService.updateFoo(data).subscribe(success, error); 
+0

Pouvez-vous juste utiliser 'resolve' comme ça, ou devez-vous le spécifier en tant que paramètre? – Matthew

+0

Bonne question, ce n'était pas évident dans le code OP posté où 'resolve' venait, donc j'ai supposé qu'il était disponible à partir d'une portée parent ou comme un global –

0

Je suppose que vous essayez de retourner une promesse, et que le code affiché est contenu dans une méthode qui ressemble à ceci:

create(): Promise<any> { 
    const data = 'whatever'; 
    return new Promise<any>((resolve, reject) => { 
    this.myService.createFoo(data).subscribe(
     (result: any) => { 
     resolve({ success: true, data: result }); 
     }, 
     err => { 
     resolve({ success: false, message: err }); 
     }); 
    }); 
} 

Si c'est le cas, plutôt que de créer manuellement une promesse, vous pouvez transformer votre Observable en une promesse en utilisant l'opérateur toPromise. Vous devrez importer d'abord si vous avez pas déjà:

import 'rxjs/add/operator/toPromise'; 

Puis, combinant avec async et await, vous pouvez transformer votre code comme suit:

async create(): Promise<any> { 
    const data = 'whatever'; 
    try { 
    const result = await this.myService.createFoo(data).toPromise(); 
    return { success: true, data: result } 
    } catch (err) { 
    return { success: false, message: err }; 
    } 
}