Async/Await 返回值问题
发布于 7 年前 作者 leavesdrift 7185 次浏览 来自 问答

我想遍历存放markdown文件的目录,文件目录可能会有很多级,忽略隐藏目录(例如.git),最终目的是取出这个目录中所有的.md文件,返回包含这些文件绝对路径的数组。

// fs-promise.js

const fs = require('fs')

exports.readdir = function(dir){
  return new Promise((resolve,reject) => {
    fs.readdir(dir,(err,docs) => {
      if(err){
        reject(err)
        return
      }
      resolve(docs)
    })
  })
}

exports.readFile = function(file,options){
  return new Promise((resolve,reject) => {
    fs.readFile(file,options,(err,data) => {
      if(err){
        reject(err)
        return
      }
      resolve(data)
    })
  })
}

exports.readFiles = function(files,options){
  let arr = []
  for(let i=0;i<files.length;i++){
    arr.push(new Promise((resolve,reject) => {
      fs.readFile(files[i],options,(err,data) => {
        if(err){
          reject(err)
          return
        }
        resolve([files[i],data])
      })
    }))
  }
  return arr
}

exports.stat = function(file){
  return new Promise((resolve,reject) => {
    fs.stat(file,(err,stats) => {
      if(err){
        reject(err)
        return
      }
      resolve(stats)
    })
  })
}

exports.stats = function(files){
  let arr = []
  for(let i=0;i<files.length;i++){
    arr.push(new Promise((resolve,reject) => {
      fs.stat(files[i],(err,stats) => {
        if(err){
          reject(err)
          return
        }
        resolve([files[i],stats])
      })
    }))
  }
  return arr
}

exports.writeFile = function(file,data,options){
  return new Promise((resolve,reject) => {
    fs.writeFile(file,data,options,(err) => {
      if(err){
        reject(err)
        return
      }
      resolve()
    })
  })
}

exports.writeFiles = function(files,data,options){
  let arr = []
  for(let i=0;i<files.length;i++){
    arr.push(new Promise((resolve,reject) => {
      fs.writeFile(files[i],data,options,(err) => {
        if(err){
          reject(err)
          return
        }
        resolve()
      })
    }))
  }
  return arr
}

//walk.js

const  fs = require('./fs-promise')
      ,{resolve} = require('path')
      ,_ = require('lodash')
      ,re1 = /\.md$/
      ,re2 = /\/\./

const walk = async function(dir,mdList=[]){

  const docs = await fs.readdir(dir)

  _.forEach(docs,(doc,idx) => {
    docs[idx] = resolve(dir,doc)
  })

  let props = await Promise.all(fs.stats(docs))

  _.forEach(props,(prop) => {

    let filename = prop[0]
       ,stat = prop[1]

    if(stat.isFile() && re1.test(filename) && !re2.test(filename)){
      mdList.push(filename)
    }else if(stat.isDirectory() && !re2.test(filename)){
      walk(filename,mdList)
    }

  })

}

walk('/home/cheng/node_projet/note')

现在问题就是我怎么取出mdList?

6 回复

我在mdList.push(filename)前面敲console.log(filename)都能如下正常输出:

/home/cheng/node_projet/note/README.md
/home/cheng/node_projet/note/Algorithm/JavaScript.md
/home/cheng/node_projet/note/Algorithm/LeetCode.md
/home/cheng/node_projet/note/Algorithm/NodeJs.md
/home/cheng/node_projet/note/Life/百科.md
/home/cheng/node_projet/note/Markdown/Markdown写作规范参考.md
/home/cheng/node_projet/note/JavaScript/Array数组.md
/home/cheng/node_projet/note/JavaScript/ECMAScript6.md
/home/cheng/node_projet/note/JavaScript/Object对象.md
/home/cheng/node_projet/note/JavaScript/回答eleme在git上的问题.md
/home/cheng/node_projet/note/JavaScript/属性描述符.md
/home/cheng/node_projet/note/JavaScript/技巧与坑.md
/home/cheng/node_projet/note/JavaScript/简写艺术.md
/home/cheng/node_projet/note/Golang/安装配置.md
/home/cheng/node_projet/note/ISO/ARP.md
/home/cheng/node_projet/note/ISO/GNS3.md
/home/cheng/node_projet/note/ISO/加密算法.md
/home/cheng/node_projet/note/ISO/网络知识.md
/home/cheng/node_projet/note/NodeJs/异步编程.md
/home/cheng/node_projet/note/NodeJs/技巧和坑.md
/home/cheng/node_projet/note/NodeJs/核心模块.md
/home/cheng/node_projet/note/NodeJs/深入浅出NodeJs.md
/home/cheng/node_projet/note/NodeJs/社区模块.md
/home/cheng/node_projet/note/NodeJs/编码加密.md
/home/cheng/node_projet/note/NodeJs/自动化脚本.md
/home/cheng/node_projet/note/Raspyberry/基础命令.md
/home/cheng/node_projet/note/Utils/chrome.md
/home/cheng/node_projet/note/Utils/git.md
/home/cheng/node_projet/note/Utils/npm.md
/home/cheng/node_projet/note/Utils/vim.md
/home/cheng/node_projet/note/System/Linux/Linux指南.md
/home/cheng/node_projet/note/System/Linux/Term终端.md
/home/cheng/node_projet/note/System/Linux/归档压缩.md
/home/cheng/node_projet/note/System/Linux/用户管理.md
/home/cheng/node_projet/note/System/Linux/网页抓取.md
/home/cheng/node_projet/note/System/Linux/设备信息.md
/home/cheng/node_projet/note/System/Windows/Windows指南.md
/home/cheng/node_projet/note/Utt/Cours/GS15.md
/home/cheng/node_projet/note/Utt/Cours/RE13.md
/home/cheng/node_projet/note/Utt/Cours/RE16.md
/home/cheng/node_projet/note/SQL/NoSQL/mongodb/mongodb的使用及技巧.md

错的太多了,重新学语法,不要强行写。

@ianchn 能详细说一下么?正在学习中

@leavesdrift forEach 那里 换成 for 里面 await walk(args),最后 return mdList, 最外层调用 walk(args).then(mdList => doSth(mdList))

@ianchn 还是不对

const  fs = require('./fs-promise')
      ,{resolve} = require('path')
      ,_ = require('lodash')
      ,re1 = /\.md$/
      ,re2 = /\/\./

const walk = async function(dir,mdList=[]){

  const docs = await fs.readdir(dir)

  _.forEach(docs,(doc,idx) => {
    docs[idx] = resolve(dir,doc)
  })

  let props = await Promise.all(fs.stats(docs))
  /*
  _.forEach(props,(prop) => {

    let filename = prop[0]
       ,stat = prop[1]

    if(stat.isFile() && re1.test(filename) && !re2.test(filename)){
      console.log(filename)
      mdList.push(filename)
    }else if(stat.isDirectory() && !re2.test(filename)){
      walk(filename,mdList)
    }

  })
  */
  for (let i=0;i<props.length;i++){
    let prop = props[i]
       ,filename = prop[0]
       ,stat = prop[1]

    if(stat.isFile() && re1.test(filename) && !re2.test(filename)){
      mdList.push(filename)
    }else if(stat.isDirectory() && !re2.test(filename)){
      walk(filename,mdList)
    }

  }

  return mdList

}

walk('/home/cheng/node_projet/note').then((mdList) => console.log(mdList))

输出结果只有根目录的那个.md文件,人生好难啊,看来不能跳genarator内部原理。

@ianchn 我少打了await,万分感谢,现在对了

回到顶部