理解节点 - 编写异步代码

时间:2017-05-01 17:40:54

标签: javascript node.js asynchronous callback

我在NodeJs上迈出了第一步。我来自Java世界,在编写异步代码时我的头脑卡住了。我在处理I / O块操作时已经阅读了很多关于异步流的内容,但我真的不知道如何解决这个问题。

当我创建“点”对象的实例以检索该点的经度和纬度时,我正在进行谷歌API调用。

在我的“app.js”流程中,我调用一个函数,在其中调用另一个需要经度和纬度的函数。如您所见,此时谷歌API调用没有回来,它的检索“未定义”。

如何以“异步方式”来思考这个问题?

+=

transform-origin

//app.js

const express = require('express');
const POI = require('./models/poi');
var app = express ();

app.get('/', (req, res) => {

    var poiA = new POI(19146, "Saraza", 2, 3);
    var poiB = new POI(19146, "Saraza", 4, 5);


    console.log(poiA.estaAXMetrosDeOtroPoi(poiB, 10));

});

app.listen(3000);

1 个答案:

答案 0 :(得分:1)

你应该知道,如果你打电话给异步功能,你就没有了它会在你的代码中的某个点完成的garantuee。这意味着

 self.geoLocalizate(direccion);
self.getCoord = () => {
        return {"latitude": self.latitude, "longitude":                                         self.longitude};
    };
...

将在

之前处理
geoCode.geocodeAddress(direccion, ...

已经完成,这就是为什么你在回调中定义的值是未定义的。真正的执行可能如下所示:例如:

var self = this;

self.latitude;
self.longitude;



self.geoLocalizate =  (direccion) => {

    //Here you make the async call, but execution continues...

};

self.geoLocalizate(direccion);

self.getCoord = () => {
    return {"latitude": self.latitude, "longitude":                                         self.longitude}; // undefined, because async has not finished
};

// NOW, async function has finished, and your callback code is executed...
if(errorMessage){
            self.latitude = null;
            self.longitude = null;
        }else{
            self.latitude = results.latitude;
            self.longitude = results.longitude;
        }
//Function throwing error, becouse of latitude, longitude "Undefined"

self.distanceBetweenPOIsCoords = (pointA, pointB) => {
    let coordA = pointA.getCoord();
    let coordB = pointB.getCoord();
    return geolib.getDistance(coordA, coordB);
};

};

另外,你不能从异步函数调用返回一些东西,你必须提供一个回调函数并将你的返回对象传递给它。为了保证正确执行,你必须包含所有需要在你的回调中完成异步功能的代码,例如:像这样

function Point (direccion, callback){

var self = this;

self.latitude;
self.longitude;

self.geoLocalizate =  (direccion) => {

    //Here i am making google API call

    geoCode.geocodeAddress(direccion, (errorMessage, results) => {
        if(errorMessage){
            self.latitude = null;
            self.longitude = null;
        }else{
            self.latitude = results.latitude;
            self.longitude = results.longitude;
        }

    self.geoLocalizate(direccion);

    self.getCoord = () => {
        return callback(null, {"latitude": self.latitude, "longitude":                                         
        self.longitude});
    };

    self.distanceBetweenPOIsCoords = (pointA, pointB) => {
        let coordA = pointA.getCoord();
        let coordB = pointB.getCoord();
        return callback(null, geolib.getDistance(coordA, coordB));
   };
  });
};