为什么下面的函数输出未定义

时间:2019-03-31 19:45:41

标签: node.js promise

我正在使用Google Places API来获取一些数据。我不知道为什么我变得不确定。我对Promise和异步程序的工作方式还不陌生。任何帮助将不胜感激。

下面的代码输出:

Searching Google Places Api for place-id: PLACE_ID_HERE_REPLACED_FOR_QUESTION

https://maps.googleapis.com/maps/api/place/details/json?placeid=PLACE_ID_HERE_REPLACED_FOR_QUESTION &fields=formatted_address,geometry,icon,id,name,permanently_closed,place_id,url,vicinity,formatted_phone_number,opening_hours,website,price_level,rating&key= API_KEY_REPLACED_HERE_FOR_QUESTION

TypeError: Cannot read property 'result' of undefined
at Promise (/srv/index.js:138:51)
    at new Promise (<anonymous>)
    at ... (/srv/index.js:137:3)
    at cloudFunction (/srv/node_modules/firebase-functions/lib/providers/https.js:57:9)
    at /worker/worker.js:783:7
    at /worker/worker.js:766:11
    at _combinedTickCallback (internal/process/next_tick.js:132:7)
    at process._tickDomainCallback (internal/process/next_tick.js:219:9)

Function execution took 192 ms, finished with status: 'crash'

如果我直接调用该URL,则会得到一个有效的结果。如果我通过代码做到这一点,我将无法定义为结果json。

function queryPlacesApiByPlaceId(placeId) {
  console.log("Searching Google Places Api for place-id: ".concat(placeId).concat());
  let url = 'https://maps.googleapis.com/maps/api/place/details/json?placeid='.concat(placeId).concat('&fields=formatted_address,geometry,icon,id,name,permanently_closed,place_id,url,vicinity,formatted_phone_number,opening_hours,website,price_level,rating').concat('&key=').concat(options.apiKey);
  console.log(url);
  https.get(url, (resp) => {
    let data = '';
    resp.on('data', (chunk) => {
      data += chunk;
    });
    resp.on('end', () => {
      return JSON.parse(data);
    });
  }).on("error", (err) => {
    console.log("Error: " + err.message);
  });
}

exports.queryPlacesApiByPlaceId = functions.https.onRequest( (req,res) => {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader( 'Content-Type', 'application/json');
  let placeId = req.query['placeId'];
  new Promise(async  (resolve,reject) => {
    resolve(await queryPlacesApiByPlaceId(placeId)['result']);
  }).then( (value) => {
    res.send(value);
  });
});

我期望返回json对象,但是关于未解决的Promise拒绝我收到一个错误。我不知道为什么我的诺言在这里会被拒绝。

由于我仍在尝试学习,因此将来将如何调试此类技巧的任何提示将不胜感激。

1 个答案:

答案 0 :(得分:1)

    resp.on('end', () => {
      return JSON.parse(data);
    });

此回调中的return语句仅在回调内部返回。它不会在回调之外返回到初始函数。 因为您正在处理异步代码,所以您需要提供对queryPlacesApiByPlaceId函数的回调,该回调将在您拥有数据时执行,或者使用Promise并在拥有数据时解决。

function queryPlacesApiByPlaceId(placeId) {
    return new Promise(resolve => {
        console.log("Searching Google Places Api for place-id: ".concat(placeId).concat());
        let url = 'https://maps.googleapis.com/maps/api/place/details/json?placeid='.concat(placeId).concat('&fields=formatted_address,geometry,icon,id,name,permanently_closed,place_id,url,vicinity,formatted_phone_number,opening_hours,website,price_level,rating').concat('&key=').concat(options.apiKey);
        console.log(url);
        https.get(url, (resp) => {
            let data = '';
            resp.on('data', (chunk) => {
                data += chunk;
            });
            resp.on('end', () => {
                resolve(JSON.parse(data));
            });
        }).on("error", (err) => {
            console.log("Error: " + err.message);
        });
    });
}