如何在单个函数中使用异步/等待

时间:2020-08-12 07:33:28

标签: node.js async-await

我正在使用Google Places API获取附近咖啡馆的列表。因此,该api最多提供60个位置,但它们出现在3个不同的页面中。要获取所有60个位置的列表,它会在第一页和第二页中提供令牌,我们可以借助它们访问其余位置。我写了一个函数,将地点ID存储在一个数组中。但是,在第一个请求中,我正在访问下一页的令牌。我面临的问题是在分配令牌之前调用了第二页的请求,因此导致错误。我该如何要求第二页等待直到分配了令牌值?​​

const request= require('postman-request');
const nearbycafes = (latitude,longitude,callback) => {
var placeids=[];
let token;
let count=0;
const url='https://maps.googleapis.com/maps/api/place/nearbysearch/json?location='+latitude+','+longitude+'&radius=1500&type=cafe&key=xyz'
request({url: url, json: true},(error,response)=>{
    console.log('ssss');
    if(error){
        callback('Error connecting to the API',undefined)
    }
    
    else if(response.body.results.length==0){
        callback('No such address exist. Try something else',undefined)
    }
    else{
            let i=0;
            //for(i;i<response.body.results.length;i++){
                placeids.push(response.body.results[0].place_id) 
            //}  
            if(response.body.next_page_token){
                 token=response.body.next_page_token;
                 count++;
                 console.log(count);
            }  
        }
        callback(undefined,{
            placeids
        })

})
console.log(count);
// if(count===1){
//     const url2='https://maps.googleapis.com/maps/api/place/nearbysearch/json?location='+latitude+','+longitude+'&radius=1500&type=cafe&key=xyz='+token+''
//     request({url: url2, json: true},(error,response)=>{
//         console.log('ssss2');
//         if(error){
//             callback('Error connecting to the API',undefined)
//         }
        
//         else if(response.body.results.length==0){
//             callback('No such address exist. Try something else',undefined)
//         }
//         else{
//                 let i=0;
//                 for(i;i<response.body.results.length;i++){
//                     placeids.push(response.body.results[i].place_id) 
//                 }    
//                 if(response.body.next_page_token){
//                     token=response.body.next_page_token;
//                     count++;
//                 }
//             }
//             callback(undefined,{
//                 placeids
//             })

//     })
// }

}

module.exports = nearbyhospitals;

2 个答案:

答案 0 :(得分:0)

您需要编写一个递归函数才能按顺序获取所有页面:

const request = require('postman-request')

function getPage (lat, long, token, cb) {
  const url = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${lat},${long}&radius=1500&type=cafe&key=xyz${token ? `&token=${token}` : ''}`
  request({ url: url, json: true }, (error, response) => {
    if (error) {
      cb(new Error('Error connecting to the API'), undefined)
    } else if (response.body.results.length === 0) {
      cb(null, [])
    } else {
      if (response.body.next_page_token) {
        getPage(lat, long, response.body.next_page_token, (err, res) => {
          if (err) {
            return cb(err)
          }
          cb(undefined, res.concat(response.body.results))
        })
      } else {
        cb(undefined, response.body.results)
      }
    }
  })
}

function nearbycafes (latitude, longitude, callback) {
  getPage(latitude, longitude, undefined, callback)
}
module.exports = nearbycafes

// just to try
nearbycafes(43.834527, 13.258358, (err, res) => {
  console.log({ err, res })
})

答案 1 :(得分:0)

不幸的是,我在上面的代码中看不到“第二个”请求。我假设第二个请求正在“回调”功能中完成。如果要确保在执行“回调”时“令牌”不为空,只需在分配后直接调用回调即可:

    else{
        let i=0;
        //for(i;i<response.body.results.length;i++){
            placeids.push(response.body.results[0].place_id) 
        //}  
        if(response.body.next_page_token){
             token=response.body.next_page_token;
             callback(undefined, { placeids: placeids });
             count++;
             console.log(count);
        }  
    }

似乎(假设为“ callback”)在“ else”子句之外。您确定大括号正确吗?

但是,最好的方法是在这种情况下避免使用诸如令牌这样的“全局”变量。您可以参数化回调并通过函数调用传递令牌。此类链接请求中的经验法则如下:

function A(callback) {
    $.ajax({
        //...
        success: function (result) {
            //...
            $.ajax({
                // ...
                success: function (result) {
                // ...
                }
            })
        }
    });
}