[英]Delete Previous Files in Directory, Create New Files and Download Newly Created Files With Nodejs
我正在創建一個簡單的節點應用程序。 我想要達到的目標:
我的應用程序將以網頁鏈接和一些關鍵字作為輸入。 現在我想根據輸入的關鍵字創建新的網頁。 因此,如果我進入優秀的程序員、優秀的問題解決者、nodejs 開發人員。 它應該創建 3 個新文件 good_programmer.php,great_problem_solver.php。 nodejs_developer.php 然后我想下載這些文件。
對於這個問題,我建議的解決方案如下:
const fs = require("fs");
const path = require("path");
const axios = require("axios");
const cheerio = require("cheerio");
const zipadm = require("adm-zip");
const zip = new zipadm();
// initialize app
const app = express();
// to handle the forms
app.use(express.urlencoded({ extended: false }))
// initialize port
const PORT = 8000;
// util functions
function deletePreviousFiles() {
return new Promise((res, rej) => {
fs.readdir(__dirname, (err, files) => {
if (err) throw err;
for (const file of files) {
if (file.includes(".php") || file.includes("sitemap.txt") || file.includes(".zip")) {
fs.unlink(path.join(__dirname, file), err => {
if (err) throw err;
});
}
}
res();
})
})
}
function generateSitemapFile(webpage, words) {
return new Promise((res, rej) => {
let keywords = words.split(",");
for (let i = 0; i < keywords.length; i++) {
let fileName = keywords[i].trim().replace(" ", "_");
let newLink = `${webpage}${fileName}.php`;
fs.appendFile(`sitemap.txt`, `${newLink}\n`, function (err) {
if (err) throw err;
});
}
res();
})
}
function generatePHPFiles(data, words) {
return new Promise((res, rej) => {
const $ = data;
$.html();
let keywords = words.split(",");
for (let i = 0; i < keywords.length; i++) {
let fileName = keywords[i].trim().replace(" ", "_");
fs.writeFile(`${fileName}.php`, $.html(), (err) => {
if (err) throw err;
})
}
res();
})
}
function createZipFile() {
return new Promise((res, rej) => {
fs.readdir(__dirname, (err, files) => {
if (err) throw err;
for (const file of files) {
if (file.includes(".php") || file.includes("sitemap.txt")) {
zip.addFile(file);
data = zip.toBuffer();
zip.writeZip("NewPhpFiles.zip");
}
}
res();
})
})
}
// controller
const startApplication = async (req, res, next) => {
try {
const webPageLink = req.body.link;
const seoKeywords = req.body.keywords;
// delete previous files on desk
await deletePreviousFiles();
console.log("Previous Files Deleted...");
// generate sitemap.txt file
await generateSitemapFile(webPageLink, seoKeywords);
console.log("Sitemap Created...");
// get web page response
let response = await axios.get(webPageLink);
const data = await cheerio.load(response.data);
console.log("Data Loaded From Page...")
// create new php files
generatePHPFiles(data, seoKeywords);
console.log("PHP Files Created...")
// create a zip file
createZipFile();
console.log("ZIP Created...")
next();
} catch (error) {
console.log(error)
}
}
const downloadFile = async (req,res) => {
try {
setTimeout(()=>{
res.download("NewPhpFiles.zip");
},1000)
} catch (error) {
console.log(error)
}
}
app.use(startApplication)
// initialize the route for application
app.post("/submit", downloadFile)
// start app
app.listen(PORT, console.log(`App is listening on port: ${PORT}...`));
所以,我正在刪除磁盤上現有的 php 文件,然后創建新文件並壓縮它們,但它不會下載新文件。 似乎創建新文件需要很多時間。
我認為你沒有完全理解 js 是如何工作的。 讓我們從那個開始。 例如,讓我們使用 deletePreviousFiles 函數。 fs.readdir 和 fs.unlink 有回調函數,你需要等待這些回調函數,以確保在函數執行時你想做的一切都完成了。 在 deletePreviousFiles 函數中,您正在等待 fs.readdir 而不是 fs.unlink。 也沒有正確處理錯誤。 有多種方法可以解決這個問題。 當然,您可以使用 callbaks 來完成,但有更簡單的解決方案。 您可以使用 fs 包提供的同步功能。 或者您可以使用 async/await 來避免回調混亂。 我強烈建議使用 fs/promise 包。
讓我們重構你的函數。
async function deletePreviousFiles() {
let files = await fs.promises.readdir(__dirname);
for (const file of files) {
if (file.includes(".php") || file.includes("sitemap.txt") || file.includes(".zip")) {
await fs.promises.unlink(path.join(__dirname, file))
}
}
}
通過這種方式,當您調用 deletePreviousFiles 函數時,您將確保您想做的一切都已完成。 (不要忘記這個函數是一個異步函數並返回一個承諾。所以你需要處理它。基本上用 await 調用)
在 downloadFile 函數中有一個超時函數。 我假設您這樣做是為了等待必要的操作。 這是錯誤的做法。 對於此類操作,您無法估計需要多長時間。 你需要確保它完成了。 不要使用超時來等待 io 操作!。
同樣在 startApplication 函數中,您使用 await 調用了一些異步函數,但您沒有調用其他一些函數。 例如,您在沒有等待的情況下調用了 generatePHPFiles。 因此,通過該行后,您將在控制台上打印文件已創建但實際上並未創建。
在其他一切之前,我認為您需要了解回調和 asyc/await 在 js 中是如何工作的。 如果您有更多問題,請隨時提出。 祝你有美好的一天 :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.