promise递归遍历文件夹

var http = require("http")
var server = http.createServer()
var fs = require('fs')
var _path = require('path');

function statp(path) {
    return new Promise(function (resolve, reject) {
        fs.stat(path, function (err, stats) {
            if (err) reject(err)
            data = {name: path, size: stats.size, isfile: stats.isFile()}
            //console.log(JSON.stringify(data))
            resolve(data)
        })
    })
}

function readdirp(path) {
    return new Promise(function (resolve, reject) {
        fs.readdir(path, function (err, datas) {
            if (err) reject(err)
            //console.log(JSON.stringify(datas))
            resolve(datas);
        })
        //resolve(datas);             //必须写在回调函数里面!!否则依旧异步执行,拿不到值
    })
}

//参考(照抄?)https://blog.csdn.net/bdss58/article/details/51377577
// 自己写时用全局变量列表也能实现这个效果,但把全局变量换成局部变量后一直因为异步执行拿不到数据
//[].concat(...res)==[666].concat.apply([],res)
//[1,2,3].map(a=>2a)=[2,4,6]
//_path.resolve(path, apath):拼接路径
/*逻辑是:
*   1,paths.map会给返回值加一层[],return [].concat(...res)会拆掉内部的一层[]
*       所以return getfiles(_path.resolve(path, apath))时不会出现两层[]
*   2,Promise.all和4个then保证同步执行
* */
function getfiles(path) {                                           //ok,递归。少任何一个return都会报错
    return statp(path).then(function (data) {                       //then1
        if (data.isfile) {
            return [data]
        } else {
            return readdirp(path).then(function (paths) {           //then2
                return Promise.all(paths.map(function (apath) {
                    return getfiles(_path.resolve(path, apath))
                }))
            }).then(function (res) {                                //then3
                return [].concat(...res)
            })
        }
    })
}

//a => a*2
//a => {return a*2}
//function(a){return a*2}
//以上三种写法等价:(a => a*2)(3)==(a => {return a*2})(3)==(function(a){return a*2})(3)==6
function getfiles_(path) {                                          //ok,递归
    return statp(path).then(data=> {
        if (data.isfile) {
            return [data]
        } else {
            return readdirp(path).then(paths=> {
                return Promise.all(paths.map(apath =>
                    getfiles(_path.resolve(path, apath))))
            }).then(res => [].concat(...res))
        }
    })
}

function f3(path) {													//ok,递归
    statp(path).then((d) => {
        if (d.isFile()) {
            c++
            console.log(c+":"+path)
        } else {
            readdirp(path).then((d) => {
                d.forEach((o, i) => f3(_path.resolve(path, o)))
            })
        }
    })
}

function getfiles1(path) {                                           //ok,非递归
    return readdirp(path).then(function (paths) {
        return Promise.all(paths.map(function (apath) {
                return statp(_path.resolve(path, apath))
            })
        )
    })
}

function getfiles2(path) {                            //有bug,非递归,foreach异步执行导致拿不到数据
    return readdirp(path).then(function (paths) {
        datas = []
        paths.forEach(function (apath) {
            statp(path + apath).then(function (data) {
                datas.push(data)
            })
        })
        return datas
    })
}

//第一次res={},第二次res=[object Promise],说明直接getfiles异步执行,必须通过then获取返回值
server.on('request', function (req, rep) {
    let path = 'E:\\IDEA\\license';
    var res=getfiles(path)
    console.log("res--->" + JSON.stringify(res));
    res.then(function (paths) {                                      //then4
        console.log("res---------->" + res);
        console.log("paths--->" + JSON.stringify(paths));
        rep.write(JSON.stringify(paths));
        rep.end('<h1>' + req.method + '</h1><br>');                 //最多只能有一个rep.end
    });
})

server.listen(8080, function () {
    console.log("start...")
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值