2017-05-01 19 views
0

私はNodeJで私の最初のステップを踏み出しています。私はJavaの世界から来て、私の頭は非同期コードを書くときに立ち往生した。 I/Oブロック操作を扱うときに非同期フローについて多くのことを読んだことがありますが、この問題の解決方法はわかりません。ノードの理解非同期コード

私はポイントの経度と緯度を取得するために "ポイント"オブジェクトのインスタンスを作成するとき私は、Google API呼び出しを行っています。

私の "app.js"フローでは、その内部にその経度と緯度を必要とする別の関数を呼び出す関数を呼び出します。ご覧のとおり、この時点でGoogle APIコールは戻ってこなかったので、「未定義」を取得しました。

この問題を「非同期方式」で考えるにはどうすればよいですか?あなたは非同期を呼び出す場合があることに注意してください

//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);

const Point = require('./point'); 
 

 
function POI (direccion, nombre) { 
 

 
    var self = this; 
 

 
    var direction = direccion; 
 

 
    var nombre = nombre; 
 

 
    var point = new Point(direccion); 
 

 

 
    self.getPoint =() => { 
 
     return point; 
 
    }; 
 

 
    self.estaAXMetrosDeOtroPoi = (otroPoi, distancia) => { 
 
     let poiDistance = point.distanceBetweenPOIsCoords(point, otroPoi.getPoint()); 
 
     return (distancia >= poiDistance); 
 
    }; 
 

 
} 
 

 
module.exports = POI;

var geolib = require('geolib'); 
 
var geoCode = require('../services/geoCode'); 
 

 
function Point (direccion){ 
 

 
    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 {"latitude": self.latitude, "longitude":           self.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); 
 
    }; 
 

 

 
};

+0

の方法は、それがJavaである方法に似ているように、あなたはコールバックに渡し、アクションが実行されたら、関数はそれを呼び出します。 –

+0

はい、私は理解していますが、私の問題をどのように解決することができますか? –

+0

https://www.slideshare.net/NishchitDhanani/async-history-javascript –

答えて

1

関数の中には、コード内のある時点で終了するガーメントがありません。それは

geoCode.geocodeAddress(direccion, ... 

が終了し、あなたのコールバックで定義する値は未定義である理由thatsの前に

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

が処理されることを意味します。実際の実行は次のようになります。例:

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); 
}; 

}

また、非同期関数呼び出しから何かを返すことができない場合は、コールバック関数を提供し、戻りオブジェクトを渡す必要があります。適切な実行を保護するには、コールバックで非同期関数を完了させるために必要なすべてのコードをラップする必要があります。非同期コードをJSで処理され、この

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)); 
    }; 
    }); 
}; 
+0

コールバックはどうすればよいですか?私はポイントインスタンスを作成するときにそれを渡す必要がありますか? (var点=新しい点(direccion)) –