2017-01-26 3 views
0
//request is a node module 
var request = require('request'); 
/** 
    * send REST web service message to server 
    * @function sendMessage 
    * @param {string} method - GET, POST, PUT, DELETE 
    * @param {string} url - server URL 
    * @param {object} json - The data to be send 
    * @param {object} cb - callback function 
    *@param{object}formData-The data related to file upload 
    * @returns void 
    */ 
    function sendMessage(type,url,method,json,retries,formData,cb){ 
     var options={ 
     url:url, 
     formData:formData, 
     json:true, 
switch (method) { 
    case 'get': 
     request.get(options, cb); 
     break; 
    case 'post': 
     envelope.token = json.token; 
     envelope.package = json.package; 
     options.body = envelope; 
     request.post(options, cb); 
     break; 
    case 'put': 
     envelope.package = json.package; 
     envelope.token = json.token; 
     options.body = envelope; 
     request.put(options, cb); 
     break; 
    case 'delete': 
     request.delete(options, cb); 
     break;  
} 

ici sendMessage() auj déjà écrit et bien utilisé dans tous les modules sans paramètre FormData (sendMessage(type,url,method,json,retries,cb)), mais pour le téléchargement de fichiers nous avons besoin de passer le chemin du fichier à l'aide formData sans modifier toutes les autres fonctions est-ce possible.Comment gérer les paramètres facultatifs avec rappel en javascript

+1

Avec autant de paramètres, je pense que vous devriez utiliser un seul objet à la place. – Lewis

+0

Oui, vous avez raison, mais il est déjà construit de cette façon et utilisé dans tous les autres modules. Le changement est impossible en ce moment. et j'ai besoin de solution sans affecter les autres modules –

+0

Vous pouvez lire ceci [Comment surcharger les fonctions en Javascript] (http://stackoverflow.com/questions/10855908/how-to-overload-functions-in-javascript/10855939# 10855939) qui couvre également les arguments facultatifs. – jfriend00

Répondre

1

Créez une nouvelle méthode qui accepte un objet en tant que paramètre, qui analyse l'objet et décide d'attribuer ou non la fonction d'origine à votre nouvelle exigence.

Marquez la méthode d'origine comme obsolète et le document pour utiliser votre nouvelle méthode, et lorsque le moment est venu, les appels à la méthode d'origine peuvent être remplacés. Quand ils sont tous remplacés, refactorisez votre nouvelle fonction pour supprimer le proxy et, en cas de confiance, supprimez l'ancienne méthode. Essayez et abscons autant de fonctionnalités que logique de la méthode originale pour garder le code DRY.

Si possible, écrivez un test que les méthodes originales et nouvelles peuvent réussir.

2

Si les deux systèmes d'appel différents que vous souhaitez prendre en charge sont ceci:

sendMessage(type,url,method,json,retries,formData,cb) 

et ceci:

sendMessage(type,url,method,json,retries,cb) 

Et l'argument de rappel est toujours nécessaire, alors, vous pouvez le faire comme cela:

function sendMessage(type,url,method,json,retries,formDataArg,cbArg) { 
    var cb = cbArg, formData = formDataArg; 
    // if we don't have a cb arg, then it must have been called with the 
    // shorter form that doesn't have formData 
    if (!cb) { 
     cb = formDataArg; 
     formData = null; 
    } 

    // continue rest of function using cb and formData as the symbols 
    // for the last two arguments 

    // ... other code here ... 

} 

Comme d'autres l'ont dit, quand vous obtenez autant d'arguments, il est souvent préférable d'utiliser un objet d'options uniques auquel vous attachez des propriétés. Ensuite, il devient beaucoup plus facile de rendre certains arguments optionnels.

Vous pouvez également trouver ce utile:

How to overload functions in javascript?


Pour votre information, il y a aussi la façon dont vous pourriez résoudre quelque chose comme ça dans une langue plus difficile dactylographiée. Vous créez une seconde fonction qui prend l'argument supplémentaire et déplace l'implémentation à cet endroit. Ensuite, la fonction d'origine devient simplement un shell qui appelle la nouvelle fonction avec null pour le nouvel argument.

function sendMessage2(type,url,method,json,retries,formDataArg,cbArg) { 
     // full implementation here with all arguments, formDataArg may be null 
} 

// original function here, calling signature unchanged 
function sendMessage(type,url,method,json,retries,cbArg) { 
    // call new implementation with arguments in the right place 
    return sendMessage2(type, url, method, json, retries, null, cbArg); 
} 

Bien que cela fonctionne et ne pas utiliser la surcharge, il est un peu un coup unique parce que vous ne voulez pas finir avec sendMesage3, sendMessage4, etc ... Probablement sendMessage2 devrait utiliser les options d'objet ce qui est beaucoup plus extensible, donc vous n'êtes pas obligé de le faire à nouveau. Ensuite, quelque temps plus tard, lorsque vous aurez plus de flexibilité, vous pourrez passer l'ancien code à l'objet options et vous débarrasser complètement de l'ensemble des deux API.

Cela pourrait ressembler à ceci:

function sendMessageOptions(options, cb) { 
    // main code here that supports formData to send the message 
    // gets arguments from the options object 
} 

// original function here, calling signature unchanged 
function sendMessage(type,url,method,json,retries,cbArg) { 
    // call new implementation with arguments in the right place 
    return sendMessageOptions({type: type, url: url: method: method, json: json: retries: retries}); 
} 

Remarque, je quittais le rappel sur les options objet, car cela rend la fonction compatible avec le typique async convention d'appel et fait callbacks inline pour l'appelant propre au code .

+0

Cela pourrait fonctionner, mais a la possibilité de devenir un cauchemar de maintenance! – AndFisher

+0

@AndFisher - Ce n'est pas un cauchemar de maintenance si vous ne continuez pas à ajouter d'autres arguments optionnels. Comme la réponse le dit déjà, la bonne façon de procéder est de passer à un objet d'options, mais l'OP a déjà dit que ce n'était pas une possibilité car ils ne peuvent pas changer tous les autres appelants pour le moment. Donc, il n'y a pas d'autre choix compte tenu de cette contrainte. Connaissez-vous d'autres moyens de répondre à la question compte tenu des contraintes proposées? – jfriend00

+0

Il ira à l'encontre du concept des commentaires doc, ce qui pourrait perturber un nouveau développeur qui pourrait hériter, mais ne pas être familier avec le projet, d'où un problème de maintenance. – AndFisher