Generators: Método recursivo para iterar utilizando Promises de Generators: Método recursivo para iterar utilizando Promises

Generators: Método recursivo para iterar utilizando Promises

☆ ¿Cómo utilizar una función recursiva para retornar valores de funciones generator?

Una función recursiva puede ser utilizada para iterar a través de yielded Promises y retornar valores a la función Generator.

function run(funGenerator) {
  // provee una función generator como argumento
  var og = funGenerator(); // crea un nuevo object generator a traves de la función provista
  function iterador(iteracion) {
    // funcion recursiva para iterar a través de los promises
    if (iteracion.done) {
      // si se completo la iteración
      return Promise.resolve(iteracion.value); // retornar el valor final de la iteración
    }
    return Promise.resolve(iteracion.value) // crea un promise resuelto con el valor de la iteracion
      .then((x) => iterador(og.next(x))) // llama de forma recursiva la función iteradora
      .catch((x) => iterador(og.throw(x))); // lanza un error si un fallo es encontrado
  }
  try {
    return iterador(og.next()); // inicia el loop recursivo
  } catch (ex) {
    return Promise.reject(x); // retorna el promise con la excepción capturada
  }
}

La función run() toma una función Generator como argumento y utiliza la función recursiva iterador() para procesar a través de todas las sentencias yield del Generator. Si una Promise es yielded, el valor valor de esta es enviado de vuelta a la función Generator. Si un entero, string un objeto son yielded entonces esos valores son enviados de vuelta a la función Generator.

Vea como la función run() es utilizada para procesar una función Generator.

function* gen() {
  var s1 = yield fetch("https://jsonplaceholder.typicode.com/posts/1");
  var j1 = yield s1.json();
  console.log(j1.title); // imprime el title del request
  var s2 = yield fetch("https://jsonplaceholder.typicode.com/posts/2");
  var j2 = yield s2.json();
  console.log(j2.title); // imprime el title del segundo request

  var matricula = yield 1006218;
  console.log(matricula);

  var nombre = yield "John";
  console.log(nombre);

  var obj = yield { nombre: "John Doe", edad: 25 };
  console.log(obj);

  return "completado";
}

run(og)
  .then((x) => console.log(x)) // "completado"
  .catch((e) => console.log(e.message)); // en caso de una excepción imprime el mensaje

Si una Promise marcada con yield es rechazada, el método run() detendrá la iteración a través de la función Generator y retornará una Promise.