nodeJsの原生Promiseを使います.

3466 ワード

指定されたフォルダの中から最大のファイル(サブフォルダを含まない)を見つけたいなら、nodeJsでどうすればいいですか?
直接にコールバックの方法を使う以外にも、多くの優雅な方法があります.
メインプログラムのコードは以下の通りで、簡潔で上品で中身があります.
var findLargest = require('./findLargest');
findLargest('E:\\fakepath').then(function(filename){
	console.log('largest file was: ', filename);
}).catch(console.err);
はい、「運転方法の訓練が終わりました.あとは車を作るだけです.」
Async版
Asyncについては、これらのリンクの紹介をご覧ください.
http://blog.fens.me/nodejs-async/
ネット上でこのようなコードが流れています.
var fs = require('fs')
var async = require('async')
var path = require('path')


module.exports = function (dir, cb) {
  async.waterfall([
    function (next) {
      fs.readdir(dir, next)
    },
    function (files, next) {
      var paths = 
       files.map(function (file) { return path.join(dir,file) })
      async.map(paths, fs.stat, function (er, stats) {
        next(er, files, stats)
      })
    },
    function (files, stats, next) {
      var largest = stats
        .filter(function (stat) { return stat.isFile() })
        .reduce(function (prev, next) {
        if (prev.size > next.size) return prev
          return next
        })
        next(null, files[stats.indexOf(largest)])
    }
  ], cb)
}
Asyncはいつも綺麗な滝のようなコードを書いていますが、!今日の討論のテーマではないです.
Promise
Promiseについての紹介は、参考にしてください.
http://www.tuicool.com/articles/AjaUjyJ
そこで、このようなコードがありました.
var fs = require('fs');
var path = require('path');
var Q = require('q');

var fs_readdir = Q.denodeify(fs.readdir)
var fs_stat = Q.denodeify(fs.stat)

module.exports = function (dir){
  //  Q   promise
  return fs_readdir(dir)
    .then(function(files){
      var promises = files.map(function(file){
        return fs_stat(path.join(dir, file));
      });
      return Q.all(promises).then(function(stats){
        return [files, stats];
      });
    })
    .then(function(data){
      var files = data[0];
      var stats = data[1];
      var largest = stats
          .filter(function(stat){return stat.isFile();})
          .reduce(function(prev, next){
            if(prev.size > next.size){
              return prev;
            }
           return next;
         });
       return files[stats.indexOf(largest)];
     });
}
これで十分に優雅に需要を満たすことができますが、!これはまだ私が欲しいものではありません.原生Promiseを使って応援します.
ES 6のPromise
var fs = require('fs');
var path = require('path');

module.exports = function (dir){
  return readDir(dir).then(getMaxStat);
}
//es6 promise
function readDir(dir){
	var readDirPromise = new Promise(function(resolve){
		fs.readdir(dir, function(err, files){
			if(err){
				throw err;
			}
			resolve({dir: dir, files: files});
		});
	});

	return readDirPromise;
}

function getMaxStat(param){
	var promises = param.files.map(function (file){
		var statPromise = new Promise(function(resolve){
			fs.stat(path.join(param.dir, file), function (err, stat){
				if(err){
					return console.error(err);
				}
				resolve(stat);
			});
		});
		return statPromise;
	});
	var maxStatPromise = new Promise(function(resolve){
		Promise.all(promises).then(function(stats){
			var maxStat = stats.reduce(function(prev, next){
				if(prev.size > next.size) return prev;
				return next;
			});
			resolve(param.files[stats.indexOf(maxStat)]);
		});
	});
	
	return maxStatPromise;
}
システムバッグ以外に、他のカバンに依存しないです.それに、相対的に優雅で、コードがあまり綺麗ではないです.さらに最適化された空間があります.