2017-05-26 65 views
0

我试图从Firebase数据库条目中获取数据。用例如下:我将查询具有纬度,经度和半径的Web API,其中使用GeoQuery库进行查询,该库提供与数据库输入项关联的数据库结构。我使用key_entered事件管理器来触发所有匹配的位置数据库条目。只读一次Firebase数据库条目并返回其值

我现在想检查关联的数据时间戳是否比现在更新,但我得到了一些挣扎,使数据超出了Promise。我知道下面的代码由于Promises的异步性质而不起作用,但是有没有可能将一次数据与一个变量相关联,例如,等待Promise返回一些东西直到继续(如等待等)?

我完全了解node.js的异步性质,但我必须将数据返回到res.send,因为它提供了一个封闭的API调用。

我也已经使用回调函数来调用数据库查询承诺,并试图将其关联到数据,这并没有工作。

function queryGeoLocation(req, res) { 
try { 
    const lat = parseFloat(req.params.lat); 
    const long = parseFloat(req.params.long); 
    const radius = parseFloat(req.params.radius); 

    let geoQuery = geoFire.query({center: [lat, long], radius: radius}); 

    data = new QueryData(); //Use this to handle data asynchronously 
    geoQuery.on("key_entered", (key, loc, dist) => { 
     isFutureEvent = false; 
     admin.database().ref("/events/").child(key).once("value").then((snapshot) => { 
      if(Date.parse(snapshot.val().date) >= Date.now()) 
       isFutureEvent = true; 
     }).catch(() => { 
     }); 
     console.log(isFutureEvent); 

     if (isFutureEvent){ 
      data.add(key, loc, dist); 
     } 
    }); 

    // When ready directly cancel the query provider and return data (since we only want to read once) 
    geoQuery.on('ready',() => { 
     geoQuery.cancel(); 
     res.send(data.getData()); 
    }); 
} catch (err) { 
    res.status(500).send("Error: " + err); 
} 

}

+0

真的,你应该在这里做的是让queryGeoLocation返回一个承诺,解决与调用者需要的数据。调用者比使用那个承诺,通过使用那个承诺的then()来回应数据的可用性。 –

+0

是的,这对我来说是一个很好的方式。我没有意识到我可以在http请求中返回一个Promise。是否有可能通过XMLHttpRequest处理这种返回,我目前在客户端使用该返回? – domna

+0

有一个名为request-promise的node.js模块,它返回一个在HTTP请求完成时解析的promise:https://www.npmjs.com/package/request-promise –

回答

0

我通过链接承诺了它自己。也许有点过于复杂,但我正在努力。

function queryGeoLocation(req, res) { 
    try { 
     const lat = parseFloat(req.params.lat); 
     const long = parseFloat(req.params.long); 
     const radius = parseFloat(req.params.radius); 

     let geoQuery = geoFire.query({center: [lat, long], radius: radius}); 

     getGeoData = function(geoQuery) { 
      return new Promise(function (resolve, reject) { 
       data = new QueryData(); 
       geoQuery.on("key_entered", (key, loc, dist) => { 
        data.add(key, loc, dist); 
       }); 

       geoQuery.on('ready',() => { 
        geoQuery.cancel(); 
        resolve(data.getData()); 
       }); 
      }); 
     }; 

     dbQuery = function (key) { 
      return new Promise(function(resolve, reject) { 
       admin.database().ref("/events/").child(key).on('value', (data) => { 
        if (Date.parse(data.val().date) < Date.now()) 
         resolve(false); 
        else 
         resolve(true); 
       }); 
      }); 
     }; 

     checkIfDateIsNewer = function(geoData) { 
      return new Promise(function (resolve, reject) { 
       for (let key in geoData){ 
        if(geoData.hasOwnProperty(key)) { 
         dbQuery(key).then((isNewer) => { 
          if (!isNewer) 
           delete geoData[key]; 
         }); 
        } 
       } 

       resolve(geoData); 
      }); 
     }; 

     getGeoData(geoQuery).then(checkIfDateIsNewer).then(function(data) { 
      res.send(data); 
     }).catch((err) => { 
      res.status(500).send("Error: " + err); 
     }); 
    } catch (err) { 
     res.status(500).send("Error: " + err); 
    } 
} 
相关问题