循环的节点保持循环

时间:2018-12-26 20:09:39

标签: javascript node.js

我使用请求来读取网站,然后使用parseString进行转换,然后另存为json。问题正在保存。看起来“ for循环”保持循环,并且在保存信息时使用var cta中的最后一个信息分配给信息。我已经尝试了asyn等待,但没有成功。预先感谢。

var fs      = require('fs');
var request = require('request');
var parseString = require('xml2js').parseString;

var json = {} ;

var cta = [
  {
    "_id": 1,
    "name": "PRWeb",
    "feedtype": "Misc",
    "feedaddress": "https://www.prweb.com/rss2/daily.xml",
    "status": true
  },
  {
    "_id": 2,
    "name": "Business Wire",
    "feedtype": "Industrie",
    "feedaddress": "https://feed.businesswire.com/rss/home/?rss=G1QFDERJXkJeGVtRVQ==",
    "status": false
  },
  {
    "_id": 3,
    "name": "News Wire",
    "feedtype": "Daily News",
    "feedaddress": "https://www.newswire.com/newsroom/rss/custom/all-press-releases",
    "status": true
  }
];

for (var i = 0; i < cta.length; i++) { 

  function getDatos(url, callback) {
      request(url, function(error, response, data){
          callback(error, response, data);
      });
  }

  if (cta[i].status === true) {
      console.log("cta: " + cta[i].feedaddress);

      agrabar = cta[i];
      console.log("agrabar:  " + agrabar.feedaddress);
      getDatos(agrabar.feedaddress, function(error, response, data){

           parseString(data, {explicitArray: false}, function (err, result) {
              if (err) {
                  return console.log('unable to parse XML');
              }

              json = {rssfeeder: agrabar, feed: result.rss.channel.item};
              console.log(json);
              fs.appendFile ("output.json", JSON.stringify(json, null, 4), function(err) {
              if (err) throw err;
              console.log('complete');
              });
          });
       });
  }

}
console.log('DONE!!!')

1 个答案:

答案 0 :(得分:0)

您似乎正在将异步代码与同步代码混合在一起。如果您阅读有关如何在Javascript中(以什么顺序)处理回调的信息,那就太好了。

示例:实际上,应该在最后一行最后一行代码console.log('DONE!!!')上打印,但是当您运行它时,您会惊讶地发现它实际上是要打印到的第一行安慰。这是因为函数getDatos是异步函数,这意味着它将在以后的某个时间点执行。您的for循环同步执行,这意味着getDatos将以正确的顺序被调用三次,但是由于JS中的函数关闭和异步性,getDatos将在您完成最后的console.log之后被调用。

此外,在现代JS中使用async awaitPromises是一个好习惯,因为它使读取代码变得更加容易。我已经修改了您的代码以执行您打算做的事情,现在就在这里。希望对您有帮助!

var fs      = require('fs');
var request = require('request');
var parseString = require('xml2js').parseString;

var cta = [
    {
        "_id": 1,
        "name": "PRWeb",
        "feedtype": "Misc",
        "feedaddress": "https://www.prweb.com/rss2/daily.xml",
        "status": true
    },
    {
        "_id": 2,
        "name": "Business Wire",
        "feedtype": "Industrie",
        "feedaddress": "https://feed.businesswire.com/rss/home/?rss=G1QFDERJXkJeGVtRVQ==",
        "status": false
    },
    {
        "_id": 3,
        "name": "News Wire",
        "feedtype": "Daily News",
        "feedaddress": "https://www.newswire.com/newsroom/rss/custom/all-press-releases",
        "status": true
    }
];

function getDatos(cta_object) {
    if (cta_object.status === false){
        return new Promise((resolve, reject) => resolve(false));
    }
    else {
        return new Promise((resolve, reject) => {
            request(cta_object.feedaddress, (err, response, data) => {
                if (err) reject(err);
                else resolve(data);
            })
        })
            .then((data) => {
                return new Promise((resolve, reject) => {
                    parseString(data, {explicitArray: false}, (err, result) => {
                        if (err) {
                            console.error("Unable to parse XML!");
                            return reject(err);
                        }
                        else return resolve(result);
                    });
                })
            })
            .then((result) => {
                console.log(result);
                return {
                    'rssfeeder': cta_object,
                    'feed': result.rss.channel.item
                };
            })
            .then((json) => {
                return new Promise((resolve, reject) => {
                    fs.appendFile ("output.json", JSON.stringify(json, null, 4), function(err) {
                        if (err) reject(err) ;
                        console.log("complete!");
                        resolve(true);
                    });
                })
            })
            .catch((err) => {
                throw(err);
            })
    }
};

Promise.all(cta.map((cta_obj) => getDatos(cta_obj)))
    .then(() => console.log('DONE!!!'))
    .catch((err) => {
        throw err;
    })