javascript, función en una función

I have some kind of error concept regarding to the creation of functions into functions, I would appreciate any help in here.

Let's say I have to apply the jquery $.post function several times, so I dont want to repeat myself, so I create something like this.

 myLoadFunction(url, function) {

     $.post(url, function( data ) {
        //something generic
     })
     .done(function(data) {
       //what I want to put on my caller function
     })
     .fail(function(data) {

       //something generic
     });

 }

so I can execute it like this:

myLoadFunction("myurlblabla", function() {
       //everything I need into the .done
});

Any ideas? I am not even sure if this is possible, so pls do not kill me :)

Saludos!

preguntado el 19 de mayo de 14 a las 15:05

Have you tried running the code? What errors are you getting? -

Where are you going to fire the callback function you passed in? You want to rename the parameter function to something less reserved. And to call it -- .done(myFunc) trabajará -

It's not clear if you have some custom code you want to run before the callback or not. -

4 Respuestas

The structure you're trying to achieve is already there for you:

Usted quiere:

myLoadFunction("myurlblabla", function() {..if success...});

But You already have it in:

myLoadFunction("myurlblabla").done(...)  // nicer right ?

Using the deferred object, it already provides this:

Change the structure to return a deferred obj: ( or better see my edit)

myLoadFunction(url) 
{
    return $.post(url, function(data) {
        //something generic
    });
}

var R = myLoadFunction("myurlblabla");

R.done(function (){ do whatever}); // here is your actual question.
R.fail(function (){ do whatever});

Also don't mix responsibilites !

myLoadFunction should do carga nada mas.

With the result of the load you can do other thing afuera of this load factory function.

don't put logic there

editar

Regarding your comment :

but on this, would I allow to preserve the same answers for fail and the generic load? I just dont want to repeat the fail case nor the case when data is empty

You could set a function ( one time) which you will reference each time : ( don't put this on global scope. an object which contains these function would be great).

function myGENERICCallback(){ something I don't want to repeat}
function mydoneCallback(){ something I don't want to repeat}
function myfailCallback(){ something I don't want to repeat}
function myAlwaysCallback(){ something I don't want to repeat}

Now - you can do this :

var R = myLoadFunction("myurlblabla");

R.done(mydoneCallback); 
R.fail(myfailCallback);

And so your load function would look like :

myLoadFunction(url) 
{
    return $.post(url, myGENERICCallback); 
}
  • myGENERICCallback would always be called
  • you load function does not contain any logic
  • you can have specific callbacks for each case
  • you keep single responsibility principle.
  • you don't repeat your code
  • you only need to change in one place
  • Other can subscribe to your deferred also.

contestado el 19 de mayo de 14 a las 15:05

This solution would allow to specify different callbacks for each. Is more flexible. - aplastar

but on this, would I allow to preserve the same answers for fail and the generic load? I just dont want to repeat the fail case nor the case when data is empty - andresmijares

@andresmijares25 What do you mean "repeat the fail case nor the case when data is empty"? - aplastar

@andresmijares25 So write them outside ( only 1 time) like var myCbFunc = function (){...}; R.done(myCbFunc); - Royi Namir

I mean, "something generic" won't vary, that is what I dont want to repeat - andresmijares

You aren't far off, you just need to call the function you pass in:

myLoadFunction(url, callback) {    
     $.post(url, function( data ) {
        //something generic
     })
     .done(function(data) {
       callback(data);
     })
     .fail(function(data) {

       //something generic
     });    
 }

Or you can pass it directly to the done function:

myLoadFunction(url, callback) {    
     $.post(url, function( data ) {
        //something generic
     })
     .done(callback)
     .fail(function(data) {

       //something generic
     });    
 }

Just don't call it 'function' as that is a protected keyword in JavaScript so won't work.

contestado el 19 de mayo de 14 a las 15:05

@Persona especial $.post(url, callback) is no good because he'd have to set .done and .fail each time - Platón

@crush i was responding to your deleted comment; simply passing the callback to post, as $.post(url, callback), will only execute callback on success. so if OP wants to handle .fail he would need to define the failure callback on every invocation of $.post - Platón

@Plato I didn't mean he should ONLY pass it to the $.post. I was showing how he might as well simply pass the callback to the function by reference instead of wrapping it in an anonymous function to execute it. However, if the OP needs to execute some code before the callback, then the inner function makes sense. I'm not sure how you came to the conclusion that you thought I meant that passing the callback to $.post would somehow magically assign it to fail y done too...that's ignorant. - aplastar

@crush sure, you could do it that way, but I think it goes against OP's request "I dont want to repeat myself" and the spirit of the question, which seems to be 'how can I create a wrapper for this chunk of asynchronous code' - Platón

@Plato I wasn't suggesting he do that outside of his encapsulating function..........I didn't understand that he had some other code other than the callback he was passing that he wanted to execute. I didn't find his question to be clear at all. After many comments, I see what he wants to do. - aplastar

I think you mean that you want to have standard calls to $.post y fail but use a different function for done cada vez.

Your code isn't too far out. One thing you can't do, though, is use function as a variable name: it's a protected word in Javascript. It's common to use fn preferiblemente.

You can then pass the function to done:

 myLoadFunction(url, fn) {
     $.post(url, function( data ) {
        //something generic
     })
     .done(fn)
     .fail(function(data) {

       //something generic
     });
 }

contestado el 19 de mayo de 14 a las 15:05

I'd do it this way (having control on both success and error handlers):

Retazo:

myLoadFunction(url, successCallback, errorCallback) {
    $.post(url, function( data ) {
        //something generic
     })
     .done(function(data) {
       //what I want to put on my caller function
       successCallback();
     })
     .fail(function(data) {
       //something generic
       errorCallback();
     });
}

Llame al:

var successHandlerHere = function() {
        console.log('success', arguments);
    },
    errorHandlerHere = function() {
        console.log('error', arguments);
    };

myLoadFunction("myurlblabla", successHandlerHere, errorHandlerHere);

contestado el 19 de mayo de 14 a las 15:05

Or as @Royi Namir suggested in another answer below, using deferred objects, being more flexible. - Nicolás Olariu

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.