Tengo un pequeño desafío y mi entendimiento con las promesas espera y esas cosas no son tan buenas en este momento, puedo necesitar ayuda para entender cómo construir mi idea.
Lo que quiero intentar es leer primero una carpeta con archivos y luego leer el contenido de cada archivo uno tras otro antes de dar el siguiente paso.
En mi código actual, el problema es que el siguiente bloque then() se ejecuta antes de que yo quiera que se ejecute.
let counter = 0; //--- const getFolder = (foldername) => { return new Promise((resolve, reject) => { fs.readdir(foldername, (err, files) => { if (err) { reject(err); return; } resolve(files); }); }); }; //--- getFolder('./filesarehere/') .then((folder) => { console.log('then 1'); let amount = Object.size(folder); console.log('amount files ' + amount); let filenames = folder; filenames.forEach((file) => { let filePath2 = __dirname + '/filesarehere/' + file; fs.readFile(filePath2, (err, data) => { if (err) throw err; if (data.length > 10) { counter++; console.log('counter ' + counter); } }); }); return counter; }) .then((data) => { console.log('then 2'); console.log(data); }) .catch((err) => console.error(err));Ahora el código anterior imprime esto en el registro de mi consola:
then 1 amount files 14 then 2 0 counter 1 counter 2 counter 3 counter 4 counter 5 counter 6 counter 7 counter 8 counter 9 counter 10 counter 11 counter 12 counter 13 counter 14la parte donde luego se imprime 2 obtiene el valor de contador 0 porque la lectura de archivos no ha terminado y luego, cuando la lectura de archivos ha comenzado, ve que el contador de archivos está impreso, pero quiero que primero lea todos los archivos y luego regrese el resultado a la siguiente parte del código, que es el siguiente código .then()
Espero que alguien pueda entender lo que quiero decir, no estoy usando mucha jerga de codificadores porque no soy un experto, solo quiero aprenderlo todo en este momento.
Solo puede usar .then() y .catch() en funciones que devuelven una Promise . Su función getFolder lo está haciendo correctamente, y el primer then() que está utilizando también es correcto. Pero el segundo then() se llama en una función que no devuelve una Promise .
No estoy seguro de cuánto estás más familiarizado con Promises y async/await , pero sugiero leer sobre ellos antes de trabajar con ellos, porque son parte de códigos asincrónicos en javascript con los que es un poco difícil trabajar si no entiendes ellos primero.
Aquí escribí una versión simplificada con async/await , espero que ayude:
// fs/promises has the same fs functions but the return a Promise // instead of getting a callback const fs = require('fs/promises'); // we can only use await in async functions, so we create a temporary // async function (async () => { let counter = 0; // await waits for a Promise to gets resolved // this returns both files and folders (directories) const files = await fs.readdir('./filesarehere'); // Promise.all get an array of Promises await Promise.all( // each async function returns a Promise, so we map our files to a Promise files.map(async (file) => { const filePath = __dirname + '/filesarehere/' + file; // only use readFile if it's a file (not a folder) const isDir = (await fs.stat(filePath)).isDirectory(); if (!isDir) { // here again we are waiting for the results of fs.readFile const data = await fs.readFile(filePath); if (data.length > 10) { counter++; } // the counter is passed into resolve function of the returned Promise return counter; } return null; }) ); console.log(counter); })();