Skip to content

Latest commit

 

History

History
116 lines (94 loc) · 3.59 KB

01.md

File metadata and controls

116 lines (94 loc) · 3.59 KB

前言

通过代码学习nodejs的一些笔记。

背景

本周主要用node实现以下功能:

  1. 读取本地的项目仓库package.json文件,然后统计用到的npm包最多的前5个包。
  2. 获取这Top5包的最近7天下载量。

思路

  1. 读取本地文件需要调用内置模块的文件系统
  2. 获取包下载量需要官方接口,且涉及到http请求

实现

  1. 本地仓库目录保持与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);
             }
         })
     }
    
  2. 获取到所有文件路径存放到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;
    }
    
  3. 将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,于是出现以下问题:

  1. 在递归函数getAllPath中就存在files某时候为undefined。
  2. 在读文件readFile函数中,全局packageArray内容不稳定,并不为我臆想中最后结果。

解决

遇到上述问题的时候,我很是想不通啊!为什么会这样啊,终于我无数个console和debug之后才意识到原来是异步的原因,于是我粗暴的将异步api换成同步api,问题得到解决。

后续

这是我学习Node的第一个练习,在实现过程中感受最大的点是同步思维的转换困难。众所周知,Node有个特点是异步IO,而我习惯了JavaScript的单线程。在以后的学习中我最应该学习的一件事应该是思想的改变:异步!