Javascript / Sails.js Le contrôleur attend que le service appelle la fonction asynchrone

Il est très simple d’utiliser un appel asnyc pour attendre la fin d’une fonction Javascript, mais il semble moins clair comment gérer un contrôleur appelant un service qui à son tour appelle une fonction asynchrone.

Supposons que j’ai une méthode asynchrone simple:

foo.fooMethod( {format: _format, stuff: _stuff }, function( error, response, body ) { if ( error ) { sails.log( error ); res.send( "Error " + error, 500 ); } res.send( body, 200 ); }); 

Dans ce scénario, mon appel asynchrone fonctionnera parfaitement si je le mets dans le contrôleur car le rappel entraînera l’envoi de la réponse lorsque la fonction de rappel sera finalement contrôlée. Cependant, si je mets cela dans un service, j’ai un problème plus intéressant.

Dans MyService, je définis cet export pour serviceCall.

 exports.serviceCall = function(options) { async.auto( { test: function( callback ) { foo.fooMethod( {format: _format, stuff: _stuff }, function( error, response, body ) { sails.log("Finished with call"); if ( error ) { sails.log( error ); callback( error ); //res.send( "Error " + error, 500 ); } callback( null, body ); //res.send( body, 200 ) }); } }, function(err, result) { sails.log("Returrning"); return result; } ); }; 

Le problème est que si j’appelle cela depuis un contrôleur, l’évidence se produit. L’appel de service est immédiatement renvoyé. Je n’ai donc aucun moyen d’obtenir la réponse de serviceCall afin de pouvoir envoyer cette réponse à l’utilisateur. Puisque je ne veux pas bloquer dans node.js, la manière appropriée d’appeler à partir d’une méthode Controller-> Service-> asynchrone n’est pas claire.

En discutant avec la merveilleuse communauté de #sailsjs sur IRC, j’ai trouvé une réponse bien meilleure que celle de passer des rappels (déteste ce modèle).

 var Promise = require('bluebird'); exports.serviceCall = function(options) { parameters = { format: options.format, stuff: options.stuff } return new Promise( function( resolve, reject ) { foo.fooMethod( parameters function( error, response, body ) { sails.log("Finished with call"); if ( error ) { sails.log( error ); throw error; } else { return resolve(response.results); } }); }) }; };