Shoot an event after several events. [closed]

0

Suppose you have several ajax requests and you want to trigger an event only when all of them are completed. Is there any elegant way in JQuery to do this?

    
asked by CStff 06.06.2017 в 18:55
source

2 answers

3

Yes, what you are looking for is Promises

What are the promises?

  

The Promise object is used for asynchronous computations. A promise represents a value that may be available now, in the future, or never.

Source: What is a promise in Javascript? ?

A call to ajax then is not a promise?

Sure, that's why you can do

$.ajax({
  url: "http://algunsitio.com/datos.php",
})
.done(function( data ) {
  if ( console && console.log ) {
    console.log( "Sample of data:", data.slice( 0, 100 ) );
  }
});

.done is just executed when ajax returns the data, so, to execute what you need you can do

$.ajax(...)
 .done(function(data) {
  $.ajax(...)
  .done(..)
});

which is not advisable, because it is not readable.

To the rescue, jquery when

link

$.when(ajax1(), ajax2(), ajax3(), ajax4()).done(function(a1, a2, a3, a4){
    // el codigo aqui se ejecuta una vez que las cuatro promesas se 
    // resolvieron
});

function ajax1() {
    // NOTE:  esta funcion debe retornar el resultado 
    //        del metodo $.ajax(),el cual es una promesa.
    return $.ajax({
        url: "someUrl",
        dataType: "json",
        data:  yourJsonData,            
        ...
    });
}

(response taken from this great response from another user in English: link )

Alternative:

Another common method in angular is to use the Q library and make Q.all

liberia Q: link

let promises = [promiseAlpha(), promiseBeta(), promiseGamma()];

$q.all(promises).then((values) => {
    console.log(values[0]); // value alpha
    console.log(values[1]); // value beta
    console.log(values[2]); // value gamma

    complete();
});

But I read that sometimes Q.all does not work correctly.

You could also become creative and have each promise execute a code and in turn fill in a variable

var promisesFulfilled = [0,0,0,0];

function promise0() {
    $.ajax({
      url: "http://algunsitio.com/datos.php",
    })
    .done(function( data ) {
      promisesFulfilled[0] = 1;
      checkPromises();
    });
}

function checkPromises() {
   //si promisesFulfilled tiene todos 1, ya se terminaron las 4.
}
    
answered by 06.06.2017 / 19:30
source
2

The simplest solution I can think of is to use Deferreds

$.when(
    // Tambien funciona con get y post
    $.ajax("/primera"),
    $.ajax("/segunda"),
    $.ajax("/tercera")
    )
    .done(function(primero, segundo, tercero){
       // lo que quieras cuando funcione
    })
    .fail(function(){
        //lo que quieras cuando fallen
    });
    
answered by 06.06.2017 в 19:24