简体   繁体   English

循环的节点保持循环

[英]node for loop keep looping

I use request to read a website then parseString to convert and later save as json. 我使用请求读取网站,然后使用parseString进行转换,然后另存为json。 The problem is saving. 问题正在保存。 Looks like "for loop" keeps looping and when is saving the information uses the last info from var cta to assign to information. 看起来“ for循环”保持循环,并且在保存信息时使用var cta中的最后一个信息分配给信息。 I have try asyn await but it didnt work. 我已经尝试了asyn等待,但没有成功。 thanks in advance. 提前致谢。

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!!!')

You seem to be mixing asynchronous code with synchronous code. 您似乎正在将异步代码与同步代码混合在一起。 It'd be great if you read more about how (and in what order) callbacks are handled in Javascript. 如果您阅读有关Javascript如何(以及以什么顺序)处理回调的更多信息,将是很棒的。

Example : Your final line of code console.log('DONE!!!') should actually be printed at the last when everything has finished, but when you'll run it, you'll be surprised that it's actually the first line to be printed to console. 示例:您应该在所有步骤完成时最后最后打印代码console.log('DONE!!!')最后一行,但是当您运行它时,您会惊讶地发现它实际上是第一行打印到控制台。 This is because the function getDatos is an asynchronous function, meaning that it will execute at some later point in time. 这是因为函数getDatos是一个异步函数,这意味着它将在以后的某个时间点执行。 Your for loop executes synchronously meaning that getDatos will be called thrice in the correct order, but owing to function closure in JS and asynchronicity, getDatos will be called after your final console.log has been done. 您的for循环同步执行,这意味着getDatos将以正确的顺序被调用三次,但是由于JS中的函数关闭和异步性,最终的console.log完成后将调用getDatos

Furthermore, it's a good practice to use async await and Promises in modern JS, since it makes reading the code much more easier. 此外,在现代JS中使用async awaitPromises是一个好习惯,因为它使读取代码更加容易。 I have modified your code to do what you intend to do and here it is. 我已经修改了您的代码以执行您打算做的事情,现在就在这里。 Hope it helps! 希望能帮助到你!

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;
    })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM