Resolución de problemas de Front End con entrevistas. Promise Pool / Sudo Null Noticias de TI

Este artículo analizará la tarea del grupo de promesas. (Código Leet 2636)

Condición de la tarea

Dada una serie de funciones asincrónicas funciones y tamaño máximo de la piscina norte. Necesitas escribir una función asincrónica. promesapiscina. ella debe regresar Promesaque finalizará cuando todas las funciones de la matriz se hayan completado funciones.

El tamaño del grupo determina el número máximo Promesa, que se pueden ejecutar simultáneamente. Función PromesaPool debería comenzar a ejecutar tantas funciones como sea posible desde la matriz funciones y tomar nuevas funciones para su ejecución cuando algunas de las que se están ejecutando Promesa están completos. Las funciones deben ejecutarse en el orden en que aparecen en la matriz. funciones. cuando es el ultimo Promesa entrará en estado resuelto, PromesaPool también debería ir al estado resuelto.

Por ejemplo, si norte = 1, promesapiscina debe realizar una función a la vez de forma secuencial. Sin embargo, si norte = 2, entonces las dos primeras funciones deben ejecutarse primero. Cuando cualquiera de estas dos funciones se completa, la tercera función (si hay una en la matriz) debería comenzar a ejecutarse, y así sucesivamente hasta que no queden más funciones por ejecutar.

De acuerdo con las condiciones del problema, todas las funciones de la matriz siempre pasan exitosamente al estado resuelto. Función promesapiscina debe volver Promesaque termina con cualquier valor.

Ejemplo

Входные данные:
functions = (
  () => new Promise(res => setTimeout(res, 300)),
  () => new Promise(res => setTimeout(res, 400)),
  () => new Promise(res => setTimeout(res, 200))
)
n = 2
Результат: ((300,400,500),500)
Объяснение:
Во входном массиве 3 функции. В них вызывается setTimeout на 300мс, 400мс, и 200mмс соответственно.
Они переходят в resolved в 300мс, 400мс, и 500мс соответственно. Результирующий promise завершается в 500мс.
В t=0, первые 2 функции начинают выполнение. Размер пула 2.
В t=300, 1-я функция завершает выполнение, а 3-я функция начинает. Размер пула 2.
В t=400, 2-я функция завершает выполнение. Больше функций в массиве functions не осталось. Размер пула 1.
В t=500, 3-я функция завершает выполнение. Размер пула 0, и результирующий promise также завершается.

Respuesta

Dejar i – índice de la función actualmente en ejecución, disponibilidadPool – el número de recursos restantes para cumplir la Promesa, completadoContar – número de Promesas completadas.

  • Si la matriz de funciones está vacía, podemos completar la Promesa resultante.

  • De lo contrario, ejecutamos la función recursiva. ejecutarSiguientedonde:

    • Toma lo siguiente a funciones, donde a igual al número de recursos disponibles.

    • Estamos reduciendo el número de recursos gratuitos. disponibilidadPool en a (availPool -= k) y ejecutar a funciones para su ejecución.

    • Al completar cada función, liberamos el recurso (availPool += 1) y aumentamos el número de funciones completadas en 1 (completedCount += 1).

    • Si todas las funciones se han completado, completamos la promesa final; de lo contrario, ejecutamos la función de forma recursiva. ejecutarSiguiente.

var promisePool = function(functions, n) {
    let i = 0;

    let availPool = n;
    let completedCount = 0;

    return new Promise((resolve, reject) => {

        if(functions.length === 0){
            resolve();
            return;
        }

        const executeNext = () => {
            const pendingFunctions = functions.slice(i, i + availPool);
            i += pendingFunctions.length;
            availPool = 0;
            pendingFunctions.forEach(func => {
                func().then(() => {
                    availPool++;
                    completedCount++;
                    if(completedCount === functions.length){
                        resolve();
                    } else {
                        executeNext();
                    }
                })
            });
        }

        executeNext();
    });
};

/**
 * const sleep = 
 * promisePool((() => sleep(500), () => sleep(400)), 1)
 *   .then(console.log) // After 900ms
 */

Encontré una tarea similar en el Concurso antes de la Oferta de dos días de Yandex. Allí el problema se complicó con detalles adicionales y se modificó, pero para solucionarlo era importante conocer este problema (Promise Pool), así como estar familiarizado con Heap/Priority Queue.

Publicaciones Similares

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *