Pergunta

I know this is a base question... but I'll try to explain.

I've been using a Deferred, but someone pointed out that I'm using it as an anti-pattern. Basically, I can use the deferred in the child module. BUT if this is an anti-pattern, what is the best way to achieve this in which the "child module" might not be there.. SO, I don't want to explicitly call the child method in the success of the parent ajax call.

So, three questions:

  1. Is this a viable way, if not - what is a good way to achieve what I am going for?

  2. Even though I am resetting the Deferred, it isn't seeming to 'reset'. Why?

  3. CAN this also be achieved coupling it with another event - ie, onload. SO< we have the ajax AND onload doing the same thing.

I have a parent module.

var Z = {};

Z.someVar = $.Deferred();

Z.a = function(){
    //methods

    //Ajax call on page: can be once or multiple calls.
    $AJAX = {
        url:...,
        dataType: ...,
        //etc..
    }.success(
      function(){
         Z.someVar.resolve();
      }
    ).error();


};

// another method that MIGHT exist.

Z.b = function(){
   var func1 = function(){
       // do some stuff
       Z.someVar = $.Deferred(); // reset it.
   }
   Z.someVar.done(function(){
      func1();
   })
}
Foi útil?

Solução

A promise is an abstraction over a single, one time calculation of a value. A promise starts pending, and then can transition to either fulfilled or rejected state. Once a promise resolved (transitioned) it can never change its state again.

Deferreds are used in exactly one - when you want to construct a promise from something that's not a promise*.

In jQuery $.ajax already returns a promise to begin with.

Z.a = function(){ // this method now returns a promise
    return $.ajax({...});
};

If we want to chain it, we can use .then :

Z.a().then(function(){
    // here a() is done.
});

You can also use a caching pattern, using $.when (Promise.resolve in most promise libraries):

Z._a = null;
Z.a = function(){
    if(z._a){ // already have the value cached:
        return $.when(z._a); // promise over the value
    }
    return $.ajax({...}).then(function(res){
        Z._a = res;
        return res; // chain
    });

};

Z.b = function(){
    return Z.a().then(function(aValue){
        // do something with value, your return value here is the resolution
        // value of the a method call.
    });
}

Now, if you want to wait for multiple calls, you can use $.when with multiple promises and get their results.

There are other, very rare use cases with aggregation

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top