数据处理后如何回复客户端? (Express + Nodejs)

时间:2018-04-29 10:24:22

标签: node.js express

我无法理解为此所需的回调。我被困在如何在获取数据后响应客户端。尝试过多次不同的方式,但无法使其发挥作用。非常感谢帮助。

app.get('/update', getdata);

function update(){
    getdata();
    //Wait for data to be fetched then respond to client
};

function getdata(i=0){
  const baseURL = "" //Empty as example

  var targets = ["" ]; //Empty as example

  var urls = targets.map(function(el) { 
    return baseURL + el; 
  })

  var alldata = {};
  if (i < urls.length){
      var url = urls[i]
      var urlsplit = targets[i].split("/");
      var categoryid = urlsplit[0]
      var id = urlsplit[1]

      console.log("Getting " + id)

      request.get(url, function(error, responce, html){
          var productdata = [];
          if (!error){
              let $ =  cheerio.load(html);
              var allitems = $("div.related-box");
              allitems.each(function(index){
                  productdata.push ({
                      "product_name": $(this).find('.name').find('a').text(),
                      "price": $(this).find('.price').children().remove().end().text().replace(/(\r\n|\n|\r)/gm,"").trim()
                  })
              })
              if (!(categoryid in alldata)){
                  alldata[categoryid] = {}; 
              }
                  alldata[categoryid][id] = productdata;
                  getdata(i+1)
          }
      });
  }
  else{
      fs.writeFile('Value.json', JSON.stringify(alldata, null, 2), function(){
          console.log("Data Saved")
      })
  }
};

2 个答案:

答案 0 :(得分:1)

getData函数getData(req, res)添加两个参数,当您的流程完成后,发送响应。 res.send(your data); res.end();

答案 1 :(得分:0)

我试图了解您的代码以及您要实现的目标,即对API进行多次异步调用(getData)获取响应并将其存储在临时对象中alldata )以便稍后处理。在完成所有API调用后,将所有数据写入文件。

虽然您必须使用res.sendres.end,但您可能必须使用promises(引用here)来执行多个异步调用,然后等待以任何方式响应在这些承诺得到解决或回复后您想要的数据。

app.get('/update', update);

function update(req, res) {
    var allAsyncFunctions = [];
    var targets = ...; //Your targets array
    var alldata = {};
    targets.forEach(function(tgt) {
        allAsyncFunctions.push(getData(tgt));
    }, this);
    Promise.all(allAsyncFunctions).then(function(values) {
        fs.writeFile('Value.json', JSON.stringify(alldata, null, 2), function() {
            console.log("Data Saved"); //Wait for data to be fetched then respond to client
            res.json({ "data": "All data saved or updated succesfully" });
        })
    });

};

function getdata(myCurrentTarget) {
    return new Promise(function(res, rej) {
        const baseURL = ""; //Empty as example
        var url = baseURL + myCurrentTarget; // As we are already traversing targets array in update function
        var urlsplit = targets[i].split("/");
        var categoryid = urlsplit[0]
        var id = urlsplit[1]

        console.log("Getting " + id)
        request.get(url, function(error, response, html) {
            var productdata = [];
            if (!error) {
                let $ = cheerio.load(html);
                var allitems = $("div.related-box");
                allitems.each(function(index) {
                    productdata.push({
                        "product_name": $(this).find('.name').find('a').text(),
                        "price": $(this).find('.price').children().remove().end().text().replace(/(\r\n|\n|\r)/gm, "").trim()
                    })
                })
                if (!(categoryid in alldata)) {
                    alldata[categoryid] = {};
                }
                alldata[categoryid][id] = productdata;
                res();
            }
        });

    });
};

HTH。