Почему приведенная ниже функция вывода не определена - PullRequest
2 голосов
/ 31 марта 2019

Я работаю с Google Места API, чтобы получить некоторые данные. Я не могу понять, почему я становлюсь неопределенным. Я все еще плохо знаком с тем, как работают обещания и асинхронные программы. Любая помощь будет принята с благодарностью.

Код ниже выводит:

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 будет возвращен, но я получаю сообщение об ошибке, что отказ от обещания не разрешен. Я не знаю, почему мое обещание будет отклонено здесь.

Буду очень признателен за советы по отладке подобных вещей в будущем, поскольку я все еще пытаюсь учиться.

1 Ответ

1 голос
/ 31 марта 2019
    resp.on('end', () => {
      return JSON.parse(data);
    });

Оператор возврата в этом обратном вызове возвращается только внутри обратного вызова. Он не вернется за пределы обратного вызова к исходной функции. Поскольку вы имеете дело с асинхронным кодом, вам необходимо либо предоставить обратный вызов для функции queryPlacesApiByPlaceId, которая будет выполняться, когда у вас есть данные, либо использовать обещания и решить, когда у вас есть эти данные.

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);
        });
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...