sincronas - promises javascript w3schools




¿Cuál es la forma más limpia de convertir Array of JQuery Promises en una promesa JQuery de una matriz? (2)

Me encuentro con la situación en la que tengo varias JQuery Promises en una matriz

var arrayOfPromises = [ $.Deferred(), $.Deferred(), $.Deferred(), $.Deferred() ]

y necesita convertirlo en una promesa jQuery de una matriz

var promiseOfArray = someTransform(arrayOfPromises)

dónde

promiseOfArray.done(function(anArray){
  alert(anArray.join(","));
});

crea una alerta con texto

resultado1, resultado2, resultado3, resultado4

Actualmente defino someTransform en coffeescript como

someTransform = (arrayOfPromises) ->
  $.when(arrayOfPromises...).pipe (promises...) ->
    promises

que se transforma en el siguiente javascript

var someTransform,
  __slice = [].slice;

someTransform = function(arrayOfPromises) {
  return $.when.apply($, arrayOfPromises).pipe(function() {
    var promises;
    promises = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
    return promises;
  });
};

Aquí hay un jsFiddle del resultado que estoy buscando.

Me preguntaba si existe una forma mejor (más corta, más limpia) de definir someTransform para lograr el mismo resultado.


Puede simplemente aplicar la matriz como argumentos a $.when .

var promiseOfArray = $.when.apply($, arrayOfPromises);

Para que el uso de este sea más claro, me gusta agregar un método a $ :

$.whenall = function(arr) { return $.when.apply($, arr); };

Ahora puedes hacer:

$.whenall([deferred1, deferred2, ...]).done(...);

Actualización: de forma predeterminada, el manejador done obtiene cada resultado pasado como un argumento separado; no obtienes una variedad de resultados.

Como necesita manejar un número arbitrario de Deferidos, puede usar el objeto especial de arguments implícitos para recorrer los resultados.

$.whenall([d1, d2, ...]).done(function() {
    for (var i = 0; i < arguments.length; i++) {
        // do something with arguments[i]
    }
});

Si realmente desea unirse al resultado de cadena de todos sus Deferreds, podemos emplear un hacker de matriz pequeña. arguments es similar a una Array , pero no es una Array :

$.whenall([d1, d2, ...]).done(function() {
    alert(Array.prototype.join.call(arguments, ','));
});

Si desea devolver una matriz de resultados a su devolución de llamada done , podemos ajustar whenall para hacerlo :

$.whenall = function(arr) {
    return $.when.apply($, arr).pipe(function() {
        return Array.prototype.slice.call(arguments);
    });
};

También me molestó mucho escribir siempre la línea "fea" $.when.apply cuando necesitamos invocarla en múltiples promesas. ¡Pero Function.prototype.bind para el rescate!

var when = Function.prototype.apply.bind( jQuery.when, null );

Ahora, podemos simplemente llamar

when( someArrayWithPromises ).done(function() {
});

Function.prototype.bind es parte de ES5 y está ampliamente disponible en todos los navegadores. Hay un montón de calzas fáciles disponibles si necesita admitir navegadores muy viejos también





promise