简体   繁体   中英

Keep the order of list node.js

I am looping through an object (I have also tried it with an array) and building a list of urls. I have tried to enumerate using for...in and to iterate using for but I keep losing the order.

 var Model = require('./model');
        var Scraper = require('./scraper');
        var Pages = [];
        function generateUrls(limit) {
          var url = 'http://www.weatheronline.co.uk/SouthAfrica/';
          var urls = [];

          Cities = {
    'Windhoek'  : 'Windhoek',
    'GraaffReinet' : 'GraaffReinet',
    'Queenstown'  : 'Queenstown',
    'Bhisho'  : 'Bhisho',
};
    };

      for (City in Cities) {
        urls.push(url + Cities[City]);
      }
      return urls;
    }
    // store all urls in a global variable  
    Pages = generateUrls();
    function wizard() {
      // if the Pages array is empty, we are Done!!
      if (!Pages.length) {
        return console.log('Done!!!!');
      }

How can I keep the order. After I scrape some of the weather data I display a table of the data on a localhost. I use node.js with mongo, express and jade.

Here is the jade code to create the table.

doctype html
html
  body
    table(style='width:100%')
      tr
        th City
        th Min
        th Max Day 1
        th Max Day 2
        th Max Day 3

      each city, i in Listings
       tr
        td 
         span= city.city
        td 
         span= city.min
        td 
         span= city.max
        td 
         span= city.maxday2
        td 
         span= city.maxday3

Thank you

Make sure you read the comments below as well because there is relevant information in them!!

For in loops don't guarantee that they will iterate over the object in a index 0 to n sort of way. A quote from here :

The for...in statement iterates over the enumerable properties of an object, in arbitrary order.

I recently came up against a similar problem and I resolved it by including an array of strings of the keys in the object which described the order that I wanted to iterate over the object in. So when I wanted to iterate over the object I just iterated over the array using a for loop and then accessed the keys using obj[key].

This has two drawbacks, first I had to write code to keep the obj and the array in sync so when things got added I to the object I needed code to update the array. Also I had to ensure that I included a hasOwnProperty check in the loop to ensure that my array was full of garbage keys.

It might not be the solution you were looking for or one that you can implement in your scenario but it certainly worked for me. Good luck!

[EDIT] Just in case I wasn't clear here is a code example:

var obj = { 
    Test1: 1,
    Test3: 3,
    Test2: 2,
    propNames: ['Test1', 'Test2', 'Test3']
};

for(var i = 0; i < obj.propNames.length; i++) {
    if (!obj.hasOwnProperty(obj.propNames[i])) continue;

    console.log(obj.propNames[i] + ": " + obj[obj.propNames[i]]);
}

// OUTPUT
// Test1: 1
// Test2: 2
// Test3: 3

I have found the problem...which creates a new problem. But I can live with the new problem. A piece of the code that I did not post in my original question is...

var numberOfParallelRequests = 20;
    for (var i = 0; i < numberOfParallelRequests; i++) {
      wizard();
    }

And that is the problem. It makes 20 requests at the same time in any order. If I make it 1 then it goes through the list one by one. The new problem is now it is very slow.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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