как работать с функциями синхронизации и асинхронности в узле - PullRequest
0 голосов
/ 08 июня 2019

Я создаю поисковую систему, и у меня есть база данных ссылок, по которой я иду, чтобы получить нужные мне результаты, но я хочу, чтобы когда я показываю результаты, я получал названия этих результатов и показывал их, но все синхронно, поэтомуон пропускает выборку заголовков и отправляет только URL

вот мой код:

app.post('/search', function(req, res){

  var resultsNum = 0;
  var results = [];
  console.log("Search Started!");

  lineReader.eachLine("searchDB.txt", function(line) {
    console.log("URL: "+line);
    getTitle(line, function(title){
      console.log("Title: "+title);
      if(similarity(req.body.searchQuery, title) > 0.9){
        resultsNum++;
        results.push(title);
      }
    });
  });
  res.send({
    "results": results
  });
});

1 Ответ

0 голосов
/ 08 июня 2019

Когда линейный ридер завершит обработку всех строк, тогда вы делаете 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() возвращает ошибку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...