如何处理节点中的同步和异步功能

时间:2019-06-07 23:35:51

标签: node.js express

我正在制作一个搜索引擎,我拥有一个链接数据库,我可以通过该链接来获取所需的结果,但是我想要在显示结果时获取这些结果的标题并显示它们,但是所有内容都是同步的,因此它会跳过标题的获取,仅发送网址

这是我的代码:

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 :(得分:0)

当行读取器完成所有行的处理后,您将执行res.send()

为了使一次管理一行和getTitle()的异步特性变得更容易,我已切换为使用内置的readline模块,该模块使我们可以暂停和恢复读数。因此,我们可以得到一行,暂停进一步的阅读,调用异步getTitle(),然后在完成getTitle()之后恢复readline实例。这样一来,即使使用异步处理,我们也可以一次读取和处理一行。

所有的行读取器完成后,将发送累积的结果。

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()的错误。如此处的代码所示,它只会跳过getTitle()返回错误的所有URL。