node中實(shí)現(xiàn)刪除目錄的幾種方法
由于刪除目錄只能刪除空目錄(如果有子文件或文件夾要先刪除)
目錄結(jié)構(gòu)算是典型的二叉樹模型,所以涉及到遍歷樹結(jié)構(gòu)
二叉樹遍歷(分為深度和廣度,以及先序,中序,后序之分)
以下以深度先序解決目錄刪除
在node中由于主線程為單線程, 可以采取串行方式和并行方式
無論用什么方法刪除,就一點(diǎn)核心: 如果是文件直接刪除, 如果不是就刪除所有子文件或子目錄, 然后記得(一定記得刪除自己)
深度先序(串行)
深度先序(串行 回調(diào)方式)
const fs = require('fs')
const path = require('path')
function rmdir(filePath, callback) {
// 先判斷當(dāng)前filePath的類型(文件還是文件夾,如果是文件直接刪除, 如果是文件夾, 去取當(dāng)前文件夾下的內(nèi)容, 拿到每一個(gè)遞歸)
fs.stat(filePath, function(err, stat) {
if(err) return console.log(err)
if(stat.isFile()) {
fs.unlink(filePath, callback)
}else {
fs.readdir(filePath, function(err, data) {
if(err) return console.log(err)
let dirs = data.map(dir => path.join(filePath, dir))
let index = 0
!(function next() {
// 此處遞歸刪除掉所有子文件 后刪除當(dāng)前 文件夾
if(index === dirs.length) {
fs.rmdir(filePath, callback)
}else {
rmdir(dirs[index++],next)
}
})()
})
}
})
}
rmdir('a', function() {
console.log('刪除成功')
})
深度先序 (串行 promise寫法)
const fs = require('fs')
const path = require('path')
function rmdirPromise(filePath) {
return new Promise((resolve, reject) => {
fs.stat(filePath, function(err, stat) {
if(err) reject(err)
if(stat.isFile()) {
fs.unlink(filePath, function(err) {
if(err) reject(err)
resolve()
})
}else {
fs.readdir(filePath, function(err, dirs) {
if(err) reject(err)
dirs = dirs.map(dir => path.join(filePath, dir)) // a/b a/c
let index = 0;
(function next() {
if(index === dirs.length) {
fs.rmdir(filePath, function(err) {
if(err) reject(err)
resolve()
})
}else {
rmdirPromise(dirs[index++]).then(() => {
next()
}, err => {
reject(err)
})
}
})()
})
}
})
})
}
rmdirPromise('a').then(() => {
console.log('刪除成功')
})
深度先序 (串行 async await寫法)
// 在node v10.0.0+版本中fs模塊提供 promise 寫法 const fs = require('fs').promises
// 如果在node 10之前的版本中可以引入第三方模塊 mz const fs = require('mz/fs') 用法一致 https://www.npmjs.com/package/mz
const fs = require('fs').promises
const path = require('path')
async function rmdirAsync(filePath) {
let stat = await fs.stat(filePath)
if (stat.isFile()) {
await fs.unlink(filePath)
} else {
let dirs = await fs.readdir(filePath)
dirs = dirs.map(dir => path.join(filePath, dir))
let index = 0;
(async function next() {
if (index === dirs.length) {
await fs.rmdir(filePath)
} else {
await rmdirAsync(dirs[index++])
await next()
}
})()
}
}
rmdirAsync('a').then(() => {
console.log('刪除成功')
}, (err) => {
console.log('err', err)
})
深度先序 (并行)
深度先序 (并行 回調(diào)寫法)
const fs = require('fs').promises
const path = require('path')
function rmdir(filePath, callback) {
fs.stat(filePath, function(err,stat) {
if(err) return console.log(err)
if(stat.isFile()) {
fs.unlink(filePath, callback)
}else {
fs.readdir(filePath, function(err, dirs) {
if(err) return console.log(err)
// 此處要添加dirs.length的驗(yàn)證,不然如果length為0 后面的forEach不執(zhí)行, 就刪不掉當(dāng)前目錄了, 也執(zhí)行不了callback
if(dirs.length === 0) {
fs.rmdir(filePath, callback)
}
dirs = dirs.map(dir => path.join(filePath, dir))
// 通過計(jì)數(shù)的方式來判斷是否子目錄都刪除了
let index = 0
function done() {
if(++index === dirs.length) {
fs.rmdir(filePath, callback)
}
}
// 何為并行? a下有兩個(gè)目錄b, c,那么同時(shí)將b, c的刪除都推到event Loop中,用for循環(huán)實(shí)現(xiàn)
dirs.forEach(dir => {
// 通過done回調(diào)的方式來控制js執(zhí)行流程(LazyMan問題也是這么解決的)
rmdir(dir, done)
});
})
}
})
}
rmdir('a', function() {
console.log('刪除成功')
})
深度先行 (并行promise寫法)
const fs = reqire('fs')
const path = require('path')
function rmdirPromise(filePath) {
return new Promise((resolve, reject) => {
fs.stat(filePath, function (err, stat) {
if (err) reject(err)
if (stat.isFile()) {
fs.unlink(filePath, function (err) {
if (err) reject(err)
resolve()
})
} else {
fs.readdir(filePath, function (err, dirs) {
if (err) reject(err)
dirs = dirs.map(dir => path.join(filePath, dir))
dirs = dirs.map(dir => rmdirPromise(dir))
Promise.all(dirs).then(() => {
fs.rmdir(filePath, resolve)
})
})
}
})
})
}
rmdirPromise('a').then(() => {
console.log('刪除成功')
})
深度先序 (并行 async + await寫法)
const fs = require('fs').promises
const path = require('path')
async function rmdirAsync(filePath) {
let stat = await fs.stat(filePath)
if(stat.isFile()) {
await fs.unlink(filePath)
}else {
let dirs = await fs.readdir(filePath)
dirs = dirs.map(dir => rmdirAsync(path.join(filePath, dir)))
await Promise.all(dirs)
await fs.rmdir(filePath)
}
}
rmdirAsync('a').then(() => {
console.log('刪除成功')
})
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
使用Node.js實(shí)現(xiàn)簡易MVC框架的方法
下面小編就為大家?guī)硪黄褂肗ode.js實(shí)現(xiàn)簡易MVC框架的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-08-08
nodejs部署到騰訊云服務(wù)器的實(shí)現(xiàn)(寶塔面板linux系統(tǒng))
本文主要介紹了nodejs部署到騰訊云服務(wù)器的實(shí)現(xiàn)(寶塔面板linux系統(tǒng)),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06
Nodejs Post請求報(bào)socket hang up錯(cuò)誤的解決辦法
這篇文章主要介紹了Nodejs Post請求報(bào)socket hang up錯(cuò)誤的解決辦法,本文因少加了headers字段信息導(dǎo)致出現(xiàn)這個(gè)錯(cuò)誤,本文給出了一個(gè)完整的實(shí)現(xiàn)代碼,需要的朋友可以參考下2014-09-09
node.js中fs文件系統(tǒng)模塊的使用方法實(shí)例詳解
這篇文章主要介紹了node.js中fs文件系統(tǒng)模塊的使用方法,結(jié)合實(shí)例形式詳細(xì)分析了node.js fs文件系統(tǒng)模塊各種常見方法的基本使用技巧與相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2020-02-02

