0

buses_near_stops begins as an empty array. Inside the asynchronous calls to the database, it is supposed to be filled. Then after the calls finish, I want to use the data inside of it. When I run this code, the final console log of buses_near_stops executes before the inner database calls, even though I have the looped calls inside of a closure. According to this post, a closure should work, but here it is doing nothing for me.

var buses_near_stops = [];
buses_near_stops.test = "TEST";


// return these fields of each location document in the database
Location.find({}, 'service_name coordinates vehicle_id last_gps_fix', function(err, doc) {
    //console.log('location found ' + JSON.stringify(doc));
    if(err){return next(err);}

         doc.forEach(function(j,k) {
         //Find a stop that is near enough to each given bus that we can say the bus is 'at' that stop
        //Making sure it returns 1 stop now because I don't know proper distance
             (function(buses_near_stops) {
                   Stop.findOne({coordinates: { $near : j.coordinates, $maxDistance: .0001}
              }, function(err, stop){
                    if(err){return next(err);}

                        console.log('stop found ' + j.service_name + " " + JSON.stringify(stop));
                        // service_name is null if bus is out of service (I believe)
                        if(stop !== null && j.service_name !== null) {
                            var service_name_of_bus = j.service_name;
                            console.log('service name of bus ' + service_name_of_bus);

                            // Find the service document associated with service_name_of_bus
                            var service_of_name = Service.findOne({name: service_name_of_bus}, function(err, service_of_name){
                                if(err){return next(err);}

                                // If the service has 'stop' on its route
                                if(service_of_name != null && service_of_name.routes[0].stops.indexOf(stop.stop_id) > -1) {
                                    console.log('stop found on service');
                                    // We have now found a bus that is stopped at a stop on its route
                                    console.log('test ' + buses_near_stops.test);
                                    buses_near_stops.push(
                                        {
                                            time: j.last_gps_fix,
                                            bus_coords: j.coordinates,
                                            stop_coords: stop.coordinates,
                                            vehicle_id: j.vehicle_id,
                                            stop_id: stop.stop_id,
                                            service_name: service_name_of_bus
                                        });

                                    console.log('length ' + buses_near_stops.length);
                                }
                            });

                        }
                    })}(buses_near_stops));

                });
                console.log('buses near stops ' + JSON.stringify(buses_near_stops));
            });
Community
  • 1
  • 1
michaelAdam
  • 1,119
  • 14
  • 30
  • Because `doc.forEach` is synchronous function, but `Stop.findOne` is asynchronous – Oleksandr T. Feb 14 '15 at 11:41
  • Yes, I'm aware of that. It is necessary that I have an asynchronous function inside the synchronous loop. That is why I put the asynchronous function in a closure. It's an attempt to make everything execute in order. – michaelAdam Feb 14 '15 at 11:44
  • @michaelAdam If you want asynchronous code to execute in order you need to use something like [`async.eachSeries`](https://github.com/caolan/async#eachSeries) instead of `forEach`. The closure was used in that other question to properly capture the value of `ans` in each iteration, it doesn't have any affect on flow control. – JohnnyHK Feb 14 '15 at 14:40
  • So the async library is just the standard way of doing this that everyone does? – michaelAdam Feb 14 '15 at 15:43
  • @michaelAdam Yep, that's probably the most popular approach. – JohnnyHK Feb 15 '15 at 16:07

0 Answers0