首页 > 解决方案 > Nodejs:使用 async/await 时如何避免嵌套 .then()

问题描述

以下是我在 nodejs 中尝试执行的操作。Rest API 将城市名称作为输入。我正在尝试使用输入城市的地理编码 API 获取纬度和经度。然后,使用纬度和经度,我试图使用另一个 API 获取最近城市的列表。然后,对于所有这些城市,我正在获取天气报告,然后对于这些城市,我正在获取是否有水,并将其作为 JSON 返回。

如您所见,有很多then,本练习的目标是避免嵌套回调。

我正在使用 async/await,它应该已经消除了嵌套的 then 函数。但我没有看到另一种方法。完整的代码片段如下。我要修复的丑陋部分是 requester.makeRequest()

以下只是必要代码的片段,而不是完整的工作代码。任何有关如何解决此问题的帮助将不胜感激。

app.get('/search', function(req, res, next) {
  const requester = {
      lastRequest: new Date(),
      makeRequest: async function(url) {
        const response = await fetch(url);
        const json = await response.json();
        return json;
      }
  };

requester.makeRequest(geocode_url +`?locate=${req.query.q}&json=1`
    + geocode_token)
  .then(function(city){
    var final_result = []
    var lat = city.latt;
    var long = city.longt;
    // request to get list of cities closer to that location,
    //takes latitude and longitude as parameters
    requester.makeRequest(metaweather_url + '?lattlong='
     + lat + ',' + long)
    .then(function(closer_cities) {
      var cities_len = closer_cities.length
      for(i = 0; i < closer_cities.length; i++) {
        woeid = closer_cities[i].woeid
        //request to get weather using woeid parameter
        requester.makeRequest(woeid_url + woeid)
        .then(function(weather) {
          var lattlong = weather.latt_long;
          requester.makeRequest(onwater_url+ lattlong +
          '?access_token=' + water_access_token)
          .then(function(onwater) {
            var temp = Object.assign(weather, onwater)
            final_result.push(temp)
            if (final_result.length == cities_len) {
              res.status(200).json({error: false,
                data: {message: final_result}})
            }
          })
        })
       }
      })
    })
  })

标签: javascriptnode.js

解决方案


我会说你还需要一个

requester.makeRequest(geocode_url +`?locate=${req.query.q}&json=1`
    + geocode_token)
  .then(async function(city){
    var final_result = []
    var lat = city.latt;
    var long = city.longt;
    // request to get list of cities closer to that location,
    //takes latitude and longitude as parameters
    closer_cities = await requester.makeRequest(metaweather_url + '?lattlong='+ lat + ',' + long);
    var cities_len = closer_cities.length;
    for(i = 0; i < closer_cities.length; i++) {
      woeid = closer_cities[i].woeid
      //request to get weather using woeid parameter
      weather = await requester.makeRequest(woeid_url + woeid)
      var lattlong = weather.latt_long;
      onwater = await awaitrequester.makeRequest(onwater_url+ lattlong + '?access_token=' + water_access_token)
      var temp = Object.assign(weather, onwater)
      final_result.push(temp)
      if (final_result.length == cities_len) {
        res.status(200).json({error: false, data: {message: final_result}})
      }
    }
  })

编辑:我真的不认为我的回答与您的问题相关抱歉


推荐阅读