promesas example angularjs concurrency promise angular-promise

angularjs - example - ¿Cómo puedo limitar la concurrencia angular $ q promesa?



promesas en angular 6 (4)

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


Probé algunos métodos diferentes para hacerlo, pero al final $q.all escribir una extensión para $q que amplía su comportamiento $q.allLimit() con $q.allLimit() .

Vea el módulo angular-q-limit para más detalles.

El módulo funciona creando una función de envoltura que toma una matriz de promesas y las ejecuta en la secuencia ordenada (limitando la ejecución simultánea al límite) hasta que todas se agoten. Luego resuelve su propia promesa con los valores de retorno de todos de la misma manera que $q.all() .


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.