【发布时间】:2020-02-25 00:59:18
【问题描述】:
我正在尝试制作一个程序来验证链接是否损坏或工作。我是 JS 的新手,也是 Promise 的新手。我正在测试一个包含一个损坏的链接和一个工作的降价文件,显然,每次我运行代码时它都会运行两次(每个链接一个,如果我添加 3 个链接它会运行 3 次)。
这是我收到的输出
这是我的代码
const path = require('path');
const fs = require('fs');
const fetch = require('node-fetch');
const inputPath = process.argv[2];
const inputOptions = process.argv[3];
const inputOptionsTwo = process.argv[4];
let okLinks = [];
let okLinksCount = 0;
let notOkLinks = [];
let notOkLinksCount = 0;
const checkFilePath = () => {
let pathExt = path.extname(inputPath);
if (pathExt == '.md') {
console.log('md file')
parseFile(inputPath);
} else {
console.log('file not recognized');
}
};
const parseFile = (inputPath) => {
fs.readFile(inputPath, 'utf8', (err, data) => {
if (!err) {
const regex = new RegExp(/(https?:\/\/[^\s\){0}]+)/g);
const links = data.match(regex);
if (links) {
//function to validate, pass the links as parameter
validateLinks(links);
} else {
console.log('no links found');
}
} else {
//error reading files
console.log('an error ocurred');
console.error(error.message);
}
});
};
const validateLinks = (links) => {
for (let i = 0; i < links.length; i++) {
const p = new Promise(resolve => {
fetch(links[i])
.then(res => {
if (res.status >= 400) {
notOkLinksCount++;
notOkLinks.push(links[i] + ' FAIL : ' + res.status);
} else {
okLinks.push(links[i] + ' OK : ' + res.status);
okLinksCount++;
}
console.log('f');
if (inputOptions === '--validate') {
setTimeout(function() {
console.log(notOkLinks);
console.log(okLinks);
}, 500);
} else if (inputOptions === '--stats' && inputOptionsTwo === '--validate') {
setTimeout(function() {
console.log('Total: ' + links.length + '\n' + 'Ok: ' + okLinksCount);
console.log('Broken: ' + notOkLinksCount);
console.log(notOkLinks);
console.log(okLinks);
}, 2800);
} else if (inputOptions === '--stats') {
setTimeout(function() {
console.log('Total: ' + links.length + '\n' + 'Ok: ' + okLinksCount);
}, 2800);
}
}).catch((error) => {
console.error('Error');
});
})
}
}
checkFilePath();
【问题讨论】:
-
您确定它运行两次,而不仅仅是登录控制台两次?
-
validateLinks()的实现有点奇怪,这让我想知道这是否是您感到困惑的部分原因。这是一个for循环(遍历所有链接),然后是fetch()每个链接。但是,整个循环都包含在一个 Promise 中,但是您永远不会解决该 Promise,因此您无法知道所有fetch()操作何时完成,事实上,所有fetch()操作都在并行运行并且将以随机顺序完成(因此以随机顺序登录)。这可能会导致您的输出日志的阅读混乱。 -
而且,代码包含许多
setTimeout()函数,它们只记录数据,再次进一步混淆输出,因此您无法知道所有输出的时间。 -
您可以在您的环境中使用
await/async语法吗?它应该可以更容易地理解承诺的代码。
标签: javascript node.js loops promise