angularjs - promesas - promise angular 6




¿Cómo puedo limitar la concurrencia angular $ q promesa? (3)

Creo que podrías hacer algo recursivo.

Esto te permitiría usar solo $q . Solo tendrías que tener una lista que $q.all usando, que de todos modos necesitas para $q.all

self.MakeCall = function(theList, chunkSize){
   //Split list into what will be processed and what should be held
    var processList = theList.slice(0,chunkSize);
    var holdList = theList.slice(chunkSize);

    return $q.all(processList).then(function(result) {
      //If holdList is empty you are finished
      if(holdList <= 0) {
        return result;
      }
      else {
        //More items make recursive call to process next set
        return self.MakeCall(holdList, chunkSize);
      }
    });
  };
//Initialize Recursive call
self.MakeCall(self.contacts);

¿Cómo hago algo como $q.all pero limitando cuántas promesas se ejecutan al mismo tiempo?

Mi pregunta es como ¿Cómo puedo limitar la concurrencia de promesas de Q?

Quiero no más de 5 procesos engendrados a la vez

La respuesta aceptada para esa otra pregunta es una biblioteca escrita para la promesa que se completó para que funcione con Q. Pero estoy interesado específicamente en una solución para $q Angular en lugar de Q

Antecedentes: el problema está siendo resuelto:
Tengo un montón de archivos para descargar en 2 pasos: a) Obtener URL b) descargar archivo.
El navegador limita la cantidad de archivos que se pueden recuperar al mismo tiempo, por lo que cuando el uso directo de las promesas con $q.all desencadena todas las descargas, solo N ocurre de inmediato, por ejemplo, 6 en Chrome, mientras que el resto se retrasa. (ver Conexiones máximas paralelas http en un navegador? )
El problema es que las URL tienen vencimiento, por lo que cuando el navegador ejecuta la descarga del archivo N + 1 , la URL ya no es válida.
Así que quiero hacer algo como throttled.all(6, promises) lugar de $q.all(promise)


Aquí hay una solución alternativa que ejecutará Chunks simultáneos. No es tan limpio como la otra respuesta, pero está más cerca de lo que estás buscando.

Dejé un marcado usado para validación.

self.list [...];

self.MakeCall = function(theList, chunkSize,methodTracker){
    //Set default chunkSize
    chunkSize = (chunkSize)?chunkSize:1;

    //Slice list using previously defined list 
    // so multiple instances can be runuse same list
    var processList = self.list.slice(0,chunkSize);
    self.list = self.list.slice(chunkSize);

    return $q.all(processList).then(function(result) {
      //If holdList is empty you are finished
      if(self.list <= 0) {
        console.debug("method last: " + methodTracker);
        return result;
      }
      else {
        //More items make recursive call to process next set
        console.debug("method: " + methodTracker);
        return self.MakeCall(self.list, chunkSize,methodTracker);
      }
    });
  };
  //Initialize Recursive call
  self.MakeCall(self.list,1,1).then(function() {
    console.warn('end 1');
  });
  //Initialize Second call that will run asynchronous with the first
  // this can be initialized as many times as you want concurrent threads
  self.MakeCall(self.list,1,2).then(function() {
    console.warn('end 2');
  });

Opté por poner otra respuesta. Creo que los dos son lo suficientemente diferentes como para no querer hacer cambios en el otro


Si la resolución de 'todas' las promesas es irrelevante (como si estuviera actualizando algunos elementos en la página y no le importa si es progresiva y no en un 'whoosh'), he creado un servicio de TaskQueue simple. No esperará a que se resuelvan todas las promesas, sino que procesará todas las promesas / funciones / tareas añadidas que se obtengan y con un máximo. concurrencia de un valor límite configurado.

Como solo encontré esto y algunos otros s que no me ayudaron con mi problema, lo hice. Así que ahora le doy algo a la comunidad, supongo. Espero que ayude a alguien.

Utiliza elementos modernos de JS como las expresiones const y lambda, pero simplemente puedes dejar que se compile desde un precompilador como babel si solo quieres las cosas 'viejas'.

https://gist.github.com/Blackskyliner/8b1bafed326044fa4f8b1ba2627d1117

Simplemente procesa su cola después de que se agregan Tareas, que son solo funciones anónimas que devuelven una promesa o valor. Se adherirá a una variable configurable 'maxConcurrentTasks' en el servicio.

Si la Tarea devuelve una promesa que devuelve una promesa, y así sucesivamente, siempre usará la "ranura" inicial dentro de la cola. Por lo tanto, liberará la "ranura" de otra tarea adicional después de que se resuelva (o rechace) toda la cadena Promesa de tareas.





angular-promise