//notes on node.js async code style, using the file list program as an example //here's the original working program.... var fs = require('fs'); fs.readdir(process.cwd(), (err, files) => { console.log(''); if(!files.length){ return console.log(' \033]31m No files to show!\033[39m\n'); } console.log(' Select which file or directory you want to see\n'); function file(i){ var filename = files[i]; fs.stat(__dirname + '/' + filename, (err, stat) => { if(stat.isDirectory()){ console.log(' '+ i +' \033[36m' + filename + '/\033[39m'); } else { console.log(' '+ i +' \033[90m'+ filename +'\033[39m'); } i++; if(i == files.length){ console.log(''); process.stdout.write(' \033[33mEnter your choice: \033[39m'); process.stdin.resume(); } else { file(i); } }); } file(0); }); //the output looks like this Davids-MacBook-Pro:nodeBasic davidsarmaholdings$ node listFiles.js Select which file or directory you want to see 0 .flickrExclusion 1 listFiles.js 2 request.js 3 server.js 4 strippedDownServer.js Enter your choice: 1 ///////////////////////////////// //confusing iteration, recursive or while loop or something function file(i){ var filename = files[i]; fs.stat(__dirname + '/' + filename, (err, stat) => { if(stat.isDirectory()){ console.log(' '+ i +' \033[36m' + filename + '/\033[39m'); } else { console.log(' '+ i +' \033[90m'+ filename +'\033[39m'); } i++; if(i == files.length){ console.log(''); process.stdout.write(' \033[33mEnter your choice: \033[39m'); process.stdin.resume(); } else { file(i); } }); } file(0); //here's what's going on in there function foo(i){ do whatever action for each element of the iteration i++; if(i == length){ stop; do whatever action at the end of the iteration; } else { foo(i); } } foo(i); ///////////////////////////////// //here's what standard loop-style iteration would look like for (var i = 0; i < length; i++){ do whatever action for each element of the iteration } do whatever action at the end of the iteration ///////////////////////////////// //can we write file function in standard iteration style? var fs = require('fs'); fs.readdir(process.cwd(), (err, files) => { console.log(''); if(!files.length){ return console.log(' \033]31m No files to show!\033[39m\n'); } console.log(' Select which file or directory you want to see\n'); for(var i = 0; i < files.length; i++){ var filename = files[i]; fs.stat(__dirname + '/' + filename, (err, stat) => { if(stat.isDirectory()){ console.log(' '+ i +' \033[36m' + filename + '/\033[39m'); } else { console.log(' '+ i +' \033[90m'+ filename +'\033[39m'); } }); } console.log(''); process.stdout.write(' \033[33mEnter your choice: \033[39m'); process.stdin.resume(); process.stdin.setEncoding('utf8'); }); //the output looks like this Davids-MacBook-Pro:nodeBasic davidsarmaholdings$ node listFiles_01.js Select which file or directory you want to see Enter your choice: 6 strippedDownServer.js 6 strippedDownServer.js 6 strippedDownServer.js 6 strippedDownServer.js 6 strippedDownServer.js 6 strippedDownServer.js //the reason is that the callback doesn't execute on loop time, so we go through the whole loop first, //and continue to execute what comes after it, then return to callback, which is using state at the end //of the iteration //the problem with this standard type of iteration is that, the after action needs to get moved inside the callback, //so that's where all the nesting comes from //ok, so what happens if we move the end action inside the callback var fs = require('fs'); fs.readdir(process.cwd(), (err, files) => { console.log(''); if(!files.length){ return console.log(' \033]31m No files to show!\033[39m\n'); } console.log(' Select which file or directory you want to see\n'); for(var i = 0; i < files.length; i++){ var filename = files[i]; fs.stat(__dirname + '/' + filename, (err, stat) => { if(stat.isDirectory()){ console.log(' '+ i +' \033[36m' + filename + '/\033[39m'); } else { console.log(' '+ i +' \033[90m'+ filename +'\033[39m'); } if(i == files.length){ console.log(''); process.stdout.write(' \033[33mEnter your choice: \033[39m'); process.stdin.resume(); } }); } }); //now the output is... Davids-MacBook-Pro:nodeBasic davidsarmaholdings$ node listFiles_02.js Select which file or directory you want to see 7 strippedDownServer.js Enter your choice: 7 strippedDownServer.js Enter your choice: 7 strippedDownServer.js Enter your choice: 7 strippedDownServer.js Enter your choice: 7 strippedDownServer.js Enter your choice: 7 strippedDownServer.js Enter your choice: 7 strippedDownServer.js Enter your choice: //Enter your choice does come at the end now, but we still shot through the loop, and executed the callback after everything //is all done