通过代码学习nodejs的一些笔记。
本周主要用node实现以下功能:
- 读取本地的项目仓库package.json文件,然后统计用到的npm包最多的前5个包。
- 获取这Top5包的最近7天下载量。
- 读取本地文件需要调用内置模块的文件系统
- 获取包下载量需要官方接口,且涉及到http请求
-
本地仓库目录保持与gitlab目录一致。首先获取所有的package.json文件所在路径,这里使用递归函数。
var fs = require('fs'); var localPath = '/Users/Documents/gitlab'; var pathArray = []; function getAllPath(path) { var files = fs.readdirSync(path); files.forEach(function (file) { var childPath = path + '/' + file; if (fs.statSync(childPath).isDirectory()) { getAllPath(childPath); } else if (file === 'package.json') { pathArray.push(childPath); } }) }
-
获取到所有文件路径存放到pathArray数组中后需要读取文件具体内容。
var packageArray = []; var packages = 0; function readFile(path) { var data = fs.readFileSync(path); //文件内容 var packageJson = JSON.parse(data.toString()); var dep = packageJson.dependencies; var devdep = packageJson.devDependencies; dep && Object.keys(dep).forEach(function (package) { packageArray = isPackageExist(packageArray, package); packages++; }) devdep && Object.keys(devdep).forEach(function (package) { packageArray = isPackageExist(packageArray, package); packages++; }) } function isPackageExist(array, package) { var index = array.findIndex(function (item) { return item.package === package; }); if (index !== -1) { array[index]['num']++; } else { array.push({ 'package': package, 'num': 1 }) } return array; }
-
将packageArray按照包的数量降序排列。然后找到这个https://github.com/npm/download-counts,根据使用文档知道只需要对它提供的api发送请求即可。
packageArray.sort(function (a, b) { return b.num - a.num; }) var https = require('https'); var packagesArray = packageArray.splice(0, 5).map(function (item) { return item.package; }) https.request({ host: 'api.npmjs.org', path: '/downloads/point/last-week/' + packagesArray, method: 'GET', }, function (response) { var data = ''; response.on('data', function (buff) { data += buff; }); response.on('end', function () { console.log(JSON.parse(data.toString())); }); }).on('error', function (e) { console.log('error:', e.message); }).end();
在实现过程中,最初用到的都是fs的异步api,于是出现以下问题:
- 在递归函数getAllPath中就存在files某时候为undefined。
- 在读文件readFile函数中,全局packageArray内容不稳定,并不为我臆想中最后结果。
遇到上述问题的时候,我很是想不通啊!为什么会这样啊,终于我无数个console和debug之后才意识到原来是异步的原因,于是我粗暴的将异步api换成同步api,问题得到解决。
这是我学习Node的第一个练习,在实现过程中感受最大的点是同步思维的转换困难。众所周知,Node有个特点是异步IO,而我习惯了JavaScript的单线程。在以后的学习中我最应该学习的一件事应该是思想的改变:异步!