Если вы можете использовать синтаксис async / await в своей среде, это облегчит рассуждение об обещаниях.
В настоящее время код не ожидает завершения асинхронного кода, поэтому я думаю, почему был добавлен setTimeouts
. Используемые таким образом, они ненадежны, потому что они делают предположение о том, сколько времени займет выполнение кода, а не ожидают его завершения или ошибок.
Старайтесь не смешивать обратные вызовы с кодом обещания, например fs.readFile
, Node предоставляет fs
API обещаний .
Библиотека обещаний Bluebird предоставляет несколько помощников и Promise.map
или Promise.filter
для работы с массивами. Также Promise.delay
, если вам нужно было использовать setTimeout
по какой-либо другой причине.
Объединение всего этого означает значительную реструктуризацию вашего кода.
const fsp = require('fs').promises;
const fetch = require('node-fetch');
const Promise = require('bluebird');
const parseFile = async (inputPath) => {
try {
const data = await fsp.readFile(inputPath, 'utf8')
const regex = new RegExp(/(https?:\/\/[^\s\){0}]+)/g);
const links = data.match(regex);
if (!links) {
return console.log('no links found');
}
//function to validate, pass the links as parameter
return validateLinks(links);
} catch (error) {
//error reading files
console.error('An error occurred processing '+inputPath);
throw error
}
};
const checkLink = async (link) => {
try {
const res = await fetch(link)
if (res.status >= 400) {
const error = new Error(`'Request failed for ${link} with ${res.status}`)
error.res = res
error.status = status
throw error
}
return link;
}
catch (error) {
error.link = link
throw error
}
}
const validateLinks = async (links) => {
const notOkLinks = [];
const okLinks = await Promise.filter(links, async link => {
try {
return checkLink(link)
}
catch (error) {
console.error('Error for %s', link, error);
notOkLinks.push(error)
return false
}
})
return {
okLinks,
notOkLinks,
}
}
Затем вы можете переопределить checkFilePath
на await parseFile()
и заняться регистрацией okLinks
и notOkLinks
, которые возвращаются в объекте. Удалите все setTimeout
s, потому что await
будет ждать обещаний до конца sh, прежде чем продолжить.