Когда линейный ридер завершит обработку всех строк, тогда вы делаете res.send()
.
Чтобы упростить управление одной строкой за раз и асинхронный характер getTitle()
, я переключился на использование встроенного модуля readline, который позволяет нам приостанавливать и возобновлять чтение. Таким образом, мы можем получить строку, приостановить дальнейшее чтение, вызвать асинхронный getTitle()
и затем возобновить экземпляр readline после выполнения getTitle()
. Это позволяет нам читать и обрабатывать строки по одной за раз даже при использовании асинхронной обработки.
Накопленные результаты затем отправляются по окончании чтения.
const readline = require('readline');
const fs = require('fs');
app.post('/search', function(req, res) {
let resultsNum = 0;
let results = [];
console.log("Search Started!");
const rl = readline.createInterface({
input: fs.createReadStream("searchDB.txt"),
crlfDelay: Infinity
});
// callback called for each new line
rl.on('line', line => {
// pause more lines until we are done with this one
rl.pause();
console.log("URL: " + line);
getTitle(line, function(title, err) {
if (err) {
// you need to decide what to do here
// do you skip it?
// do you send an error response and abort further processing
console.log(err);
rl.resume();
return;
}
console.log("Title: " + title);
if (similarity(req.body.searchQuery, title) > 0.9) {
resultsNum++;
results.push(title);
}
// start the readline interface so it will trigger the next line
rl.resume();
});
});
// listener for when readline is done
rl.on('close', () => {
res.send({
"results": results
});
});
});
Вам нужно решить, как вы хотите, чтобы обработка ошибок работала getTitle()
. Как он здесь закодирован, он просто пропускает любые URL, для которых getTitle()
возвращает ошибку.