已确认填充的对象数组返回空

时间:2018-04-09 20:06:23

标签: javascript node.js associative-array

我有一个返回对象数组时失败的方法。如标题中所述 - 确认数组已填充但响应中为空。

以下是完整的流程:

网址:

  

http://localhost:53000/api/v1/landmarks?lat=40.76959&lng=-73.95136&radius=160

路由到相应的索引:

api.route('/api/v1/landmarks').get(Landmark.list);

索引呼叫服务:

exports.list = (req, res) => {

    const landmark = new LandmarkService();

    landmark.getLandmarks(req)
        .then(landmarks => {

            var response = new Object();
                response.startindex = req.query.page;
                response.limit = req.query.per_page;
                response.landmarks = landmarks;

                res.json(response);
        })
        .catch(err => {
            logger.error(err);
            res.status(422).send(err.errors);
        });
};

服务方法使用数据访问类返回承诺

  getLandmarks(req) {

    const params = req.params || {};
    const query = req.query || {};
    const page = parseInt(query.page, 10) || 1;
    const perPage = parseInt(query.per_page, 10);
    const userLatitude = parseFloat(query.lat); 
    const userLongitude = parseFloat(query.lng); 
    const userRadius = parseFloat(query.radius) || 10;
    const utils = new Utils();
    const data = new DataService();
    const landmarkProperties = ['key','building','street','category','closing', 
            'email','name','opening','phone','postal','timestamp','type','web'];

    return data.db_GetAllByLocation(landmarksRef, landmarkLocationsRef, 
                    landmarkProperties, userLatitude, userLongitude, userRadius);

    } // getLandmarks

但是,响应始终为空。

我在被调用的方法中构建一个数组,并用JSON对象填充它。这就是应该在回复中发回的内容。在命中return语句之前,我可以确认属性数组是否已正确填充。我可以将它记录到控制台。我也可以成功发回一个填充了存根值的测试数组。

我有一种感觉,我是如何在Promise中设置的?

应该返回对象数组的数据访问方法:

db_GetAllByLocation(ref, ref_locations, properties, user_latitude, user_longitude, user_radius)
{  
        const landmarkGeoFire = new GeoFire(ref_locations);
        var geoQuery = landmarkGeoFire.query({
                center: [user_latitude, user_longitude], 
                radius: user_radius
        });
        var locations = [];
        var onKeyEnteredRegistration = geoQuery.on("key_entered", function (key, coordinates, distance) {
            var location = {}; 
                location.key = key;
                location.latitude = coordinates[0];
                location.longitude = coordinates[1];
                location.distance = distance;
                locations.push(location);                   
        });
        var attributes = [];
        var onReadyRegistration = geoQuery.on("ready", function() {
            ref.on('value', function (refsSnap) {
                   refsSnap.forEach((refSnap) => {
                        var list = refSnap;
                        locations.forEach(function(locationSnap) 
                        {
                            //console.log(refSnap.key, '==', locationSnap.key);
                            if (refSnap.key == locationSnap.key) 
                            {
                                var attribute = {};
                                for(var i=0; i<=properties.length-1; i++)
                                {
                                    if(properties[i] == 'key') {
                                        attribute[properties[i]] = refSnap.key;
                                        continue;
                                    }
                                    attribute[properties[i]] = list.child(properties[i]).val();
                                }
                                attribute['latitude'] = locationSnap.latitude;
                                attribute['longitude'] = locationSnap.longitude;
                                attribute['distance'] =  locationSnap.distance;
                                attributes.push(attribute);    
                            } // refSnap.key == locationSnap.key
                        }); // locations.forEach
                    }); // refsSnap.forEach
                    return Promise.resolve(attributes); <-- does not resolve (throws 'cannot read property .then')
                  //geoQuery.cancel();
                }); // ref.on
        }); // onreadyregistration      

        return Promise.resolve(attributes); <-- comes back empty
}

2 个答案:

答案 0 :(得分:0)

似乎data.db_GetAllByLocation是一个异步函数,因此调用解析(landmarks);在执行异步函数完成之前调用。如果data.db_GetAllByLocation返回一个promise,则调用promise中的resolve(landmarks)。

&#13;
&#13;
data.db_GetAllByLocation().then(function() {
  resolve();
})
&#13;
&#13;
&#13;

还尝试以下修改过的db_GetAllByLocation()

&#13;
&#13;
db_GetAllByLocation(ref, ref_locations, properties, user_latitude, user_longitude, user_radius)
    {       
			return new Promise(function(resolve, reject){
				const landmarkGeoFire = new GeoFire(ref_locations);

				var geoQuery = landmarkGeoFire.query({
						center: [user_latitude, user_longitude], 
						radius: user_radius
				});

				var locations = [{}];

				var onKeyEnteredRegistration = geoQuery.on("key_entered", function (key, coordinates, distance) {
					var location = {}; 
						location.key = key;
						location.latitude = coordinates[0];
						location.longitude = coordinates[1];
						location.distance = distance;
						locations.push(location);                   

				});

			   var attributes = [{}];

				var onReadyRegistration = geoQuery.on("ready", function() {
					ref.on('value', function (refsSnap) {
						   refsSnap.forEach((refSnap) => {
								var list = refSnap;
								locations.forEach(function(locationSnap) 
								{
									if (refSnap.key == locationSnap.key) 
									{
										var attribute = {};
										for(var i=0; i<=properties.length-1; i++)
										{
											if(properties[i] == 'key') {
												attribute[properties[i]] = refSnap.key;
												continue;
											}
											attribute[properties[i]] = list.child(properties[i]).val();
										}

										attribute['latitude'] = locationSnap.latitude;
										attribute['longitude'] = locationSnap.longitude;
										attribute['distance'] =  locationSnap.distance;
										attributes.push(attribute);    
									} // refSnap.key == locationSnap.key
								}); // locations.forEach
							}); // refsSnap.forEach
							// return JSON.stringify(attributes);
							return resolve(attributes);
						}); // ref.on
				

				}); // onreadyregistration

			});
            
} 
&#13;
&#13;
&#13;

答案 1 :(得分:0)

好的,我通过删除所有代码并编写一些测试逻辑来对此进行排序(我应该在发布问题之前完成此操作)。

以下流程对我有用,并且应用回我的代码,给了我正在寻找的结果。无需重新发布代码,但以下流程可能会对某些人有所帮助。

<强>路线

api.route('/api/v1/landmarks').get(Landmark.test);

<强>索引

exports.test = (req, res) => {

    const landmark = new LandmarkService();

    landmark.getLandmarksTest(req)
        .then(landmarks => {
            var final = {};
                final.attr1 = 'attr1';
                final.attr2 = 'attr2';
                final.landmarks = landmarks;
                res.json(final);
        })
        .catch(err => {
            logger.error(err);
            res.status(422).send(err.errors);
        });

};

服务方法

getLandmarksTest(req)
{

            const data = new DataService();

        data.db_PromiseTest().then(results => {
                return Promise.resolve(results);
          }).catch(err => {
                return Promise.reject(err.errors);
          });




}

数据层方法

db_PromiseTest()
{
            var stub = {
                    "name": "Madame Uppercut",
                    "age": 39,
                    "secretIdentity": "Jane Wilson",
                    "powers": [
                    "Million tonne punch",
                    "Damage resistance",
                    "Superhuman reflexes"
                    ]
                };

                 return Promise.resolve(stub);


}