【问题标题】:How to make a node.js method wait for another helper method to complete?如何让 node.js 方法等待另一个辅助方法完成?
【发布时间】:2016-11-29 11:48:28
【问题描述】:

我正在尝试使用 nodejs 创建一个简单的 api,它连接到两个公共 api。

一个api是google,另一个api是forecast.io。

此模块接收邮政编码,并使用 google api 将邮政编码转换为由 forecast.io 使用的坐标,以提供给定区域的简单天气预报。

我的主要问题是程序异步工作,有时预测 API 会继续运行,而无需等待 google api 完成成功获取所需的数据。如何防止 google api 调用被跳过? 抱歉,代码如下:

// The required modules.
var http = require("http");
var https = require("https");

//result object
var resultSet = {
    latitude :"",
    longitude:"",
    localInfo:"",
    weather:"",
    humidity:"",
    pressure:"",
    time:""

};

//print out error messages
function printError(error){
    console.error(error.message);
}

//Forecast API required information:
//key for the forecast IO app
var forecast_IO_Key = "<Here goes the key>";
var forecast_IO_Web_Adress = "https://api.forecast.io/forecast/";


//Create Forecast request string function
function createForecastRequest(latitude, longitude){
    var request = forecast_IO_Web_Adress + forecast_IO_Key + "/"
                      + latitude +"," + longitude;
    return request;
}

//Google GEO API required information:
//Create Google Geo Request
var google_GEO_Web_Adress =  "https://maps.googleapis.com/maps/api/geocode/json?address=";

function createGoogleGeoMapRequest(zipCode){
    var request = google_GEO_Web_Adress+zipCode + "&sensor=false";
    return request;
}

function get(zipCode){
    // 1- Need to request google for geo locations using a given zip
    var googleRequest = https.get(createGoogleGeoMapRequest(zipCode), function(response){
        //console.log(createGoogleGeoMapRequest(zipCode));
        var body = "";
        var status = response.statusCode;
        //a- Read the data.
        response.on("data", function(chunk){
            body+=chunk;
        });
        //b- Parse the data.
        response.on("end", function(){  
            if(status === 200){
               try{
                   var coordinates = JSON.parse(body);
                   resultSet.latitude = coordinates.results[0].geometry.location.lat;
                   resultSet.longitude = coordinates.results[0].geometry.location.lng;

                   resultSet.localInfo = coordinates.results[0].address_components[0].long_name + ", " +
                               coordinates.results[0].address_components[1].long_name + ", " +
                               coordinates.results[0].address_components[2].long_name + ", " +
                               coordinates.results[0].address_components[3].long_name + ". ";
               }catch(error){
                   printError(error.message);
               }finally{
                  connectToForecastIO(resultSet.latitude,resultSet.longitude);
               } 
            }else{
                printError({message: "Error with GEO API"+http.STATUS_CODES[response.statusCode]})
            }
        });
    });

    function connectToForecastIO(latitude,longitude){
        var forecastRequest = https.get(createForecastRequest(latitude,longitude),function(response){
           // console.log(createForecastRequest(latitude,longitude));
            var body = "";
            var status = response.statusCode;
            //read the data
             response.on("data", function(chunk){
                body+=chunk;
            });
            //parse the data
            response.on("end", function(){
                try{
                    var weatherReport = JSON.parse(body);

                    resultSet.weather = weatherReport.currently.summary;
                    resultSet.humidity = weatherReport.currently.humidity;
                    resultSet.temperature = weatherReport.currently.temperature;
                    resultSet.pressure = weatherReport.currently.pressure;
                    resultSet.time = weatherReport.currently.time;
                }catch(error){
                    printError(error.message);
                }finally{
                   console.log(resultSet);
                   // return resultSet;
                }
            });
        });    
    }
}

//define the name of the outer module.
module.exports.get = get;

【问题讨论】:

  • 将调用放在适当的位置。如果您不向我们展示您的代码,我们当然无法告诉您这些是哪些。
  • 我们需要了解更多来帮助您
  • 听起来你可以使用 Promise 或 async.series,但我们需要查看你的代码
  • 我同意 Bergi 和 james_womack 7 - 如果你想得到帮助,你需要分享你的代码。使用jsfiddle.net 输入您的代码,并更新您的问题。
  • 那里,刚刚添加了代码,抱歉我第一次没有放。 @Bergi

标签: javascript node.js


【解决方案1】:

您的问题的最佳解决方案是使用promise。它们很容易实现并防止回调地狱!

【讨论】:

  • 我是节点新手,我什至不知道回调是什么,如果我知道它是什么,我不介意在这里使用回调。
  • 看看这个article,它会让你对回调有一个公平的了解,然后阅读promise,你就会明白你哪里出错了。跨度>
  • @CarlosLuis:回调是指您将函数作为参数传递,然后调用该函数。在以下示例中,b 是一个函数:function a (b) { b() // call b back}。这允许您在异步过程完成时运行代码,方法是将代码作为函数传递给需要执行异步操作的函数。这就像https.get() 的工作方式。你可以自己实现类似的东西。
  • 感谢资源链接的解释和坦克。正是我需要将我的学习提升到一个新的水平。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-27
  • 2012-07-10
  • 1970-01-01
相关资源
最近更新 更多