同异步编码进阶

92 阅读1分钟

使用到的API

  • fs.mkdirSync() fs.mkdir() //(同,异步)创建文件夹
  • fs.rmdirSync() fs.rmdir() //(同,异步)删除文件夹
  • fs.readdirSync() fs.readdir()//(同,异步)读取文件
  • fs.statSync() fs.stat() // (同,异步)显示文件信息
  • fs.unlinkSync() fs.unlink()//(同,异步)删除文件或符号链接

逻辑

要求:删除文件夹需要清空内部所有的文件和子级文件夹

同步删除

同步深度优先

function rmdirSync(directory) {
  //读取文件夹内部内容
  let dirs = fs.readdirSync(directory)
  //读取的文件改成相对路径
  dirs = dirs.map(dir => path.resolve(directory, dir))
  dirs.forEach(dir => {
    //显示文件信息
    let statObj = fs.statSync(dir)
    if (statObj.isDirectory()) {
      rmdirSync(dir)
    } else {
      //删除文件
      fs.unlinkSync(dir)
    }
  })
  //结束后删除整体文件夹
  fs.rmdirSync(directory)
}

同步深度优先

function rmdirSync(directory) {
   let stack =[directory]
   let index =0
   let current
   while (current =stack[index++]) {
        let statObj =fs.statSync(current)
        if (statObj.isFile()) {
            fs.unlinkSync(current)
        }else{
            stack=[...stack,...fs.readdirSync(current).map(dir=>path.resolve(current,dir))] 
        } 
   }
      const trueArr =stack.filter(el=> fs.existsSync(el))
      let idx = trueArr.length;
    while(idx--){
    fs.rmdirSync(trueArr[idx])
    }
}
rmdirSync('./a')

异步删除

普通的异步并行

function rmdir(directory, callback) {
    fs.stat(directory, function (err, statObj) {
        if (err) return callback(err);
        if (statObj.isDirectory()) {
            fs.readdir(directory, (err, dirs) => {
                dirs = dirs.map(dir => path.resolve(directory, dir))
                let times = 0;
                if(dirs.length === 0) return fs.rmdir(directory, callback)
                function done() {
                    if (++times == dirs.length) {
                        fs.rmdir(directory, callback)
                    }
                }
                dirs.forEach(dir => { 
                    rmdir(dir, done)
                })
            })
        } else {
            fs.unlink(directory, callback)
        }
    })
}

通过promise处理

function rmdir(directory) {
    return new Promise((resolve,reject)=>{
        fs.stat(directory, function (err, statObj) {
            if (err) return reject(err);
            if (statObj.isDirectory()) {
                fs.readdir(directory, (err, dirs) => {
                    // a -> b,c
                    dirs = dirs.map(dir => rmdir(path.resolve(directory, dir)))
                    Promise.all(dirs).then(()=>{// all方法自动处理了
                        fs.rmdir(directory, resolve)
                    })
                })
            } else {
                fs.unlink(directory, callback)
            }
        })
    })
}

通过async await处理

async function rmdir(directory) {
    let statObj = await fs.stat(directory)
    if (statObj.isFile()) {
         fs.unlink(directory)
    }else{
        let dirs =await fs.readdir(directory)
         dirs =dirs.map(el=>rmdir(path.resolve(directory,el)))
         await Promise.all(dirs)
         await fs.rmdir(directory)
    }
}
rmdir('./a')