2017-11-11 88 views
0

我正在編寫一個使用nativescript-geolocation API的簡單應用程序。 函數getCurrentLocation基本上可以正常工作,但是當我移動到另一個名爲maps-module.js的文件並從文件detail.js的主線程調用它時,它返回的對象位置爲NULL。 打印後控制對象,我意識到變量returned_location是在函數完成查找位置之前返回的。 我認爲它的多線程問題,但我真的不知道如何解決它。 這是我的文件。NativeScript - 地理位置:使用getCurrentLocation承諾函數的正確方法

detail.js

var Frame = require("ui/frame"); 
var Observable = require("data/observable"); 

var MapsModel = require("../../view-models/maps-model"); 


var defaultMapInfo = new MapsModel({ 
    latitude: "10.7743332", 
    longitude: "106.6345204", 
    zoom: "0", 
    bearing: "0", 
    tilt: "0", 
    padding: "0" 
}); 

var page; 
var mapView; 

exports.pageLoaded = function(args) { 
    page = args.object; 
    var data = page.navigationContext; 
    page.bindingContext = defaultMapInfo; 
} 

exports.onBackTap = function() { 
    console.log("Back to home"); 
    var topmost = Frame.topmost(); 
    topmost.goBack(); 
} 

function onMapReady(args) { 
    mapView = args.object; 
    mapView.settings.zoomGesturesEnabled = true; 
} 

function onMarkerSelect(args) { 
    console.log("Clicked on " + args.marker.title); 
} 

function onCameraChanged(args) { 
    console.log("Camera changed: " + JSON.stringify(args.camera)); 
} 

function getCurPos(args) { 
    var returned_location = defaultMapInfo.getCurrentPosition(); // variable is returned before function finished 
    console.dir(returned_location); 
} 


exports.onMapReady = onMapReady; 
exports.onMarkerSelect = onMarkerSelect; 
exports.onCameraChanged = onCameraChanged; 
exports.getCurPos = getCurPos; 

地圖 - module.js

var Observable = require("data/observable"); 

var Geolocation = require("nativescript-geolocation"); 
var Gmap = require("nativescript-google-maps-sdk"); 

function Map(info) { 
    info = info || {}; 
    var _currentPosition; 

    var viewModel = new Observable.fromObject({ 
     latitude: info.latitude || "", 
     longitude: info.longitude || "", 
     zoom: info.zoom || "", 
     bearing: info.bearing || "", 
     tilt: info.bearing || "", 
     padding: info.padding || "", 
    }); 

    viewModel.getCurrentPosition = function() { 
     if (!Geolocation.isEnabled()) { 
      Geolocation.enableLocationRequest(); 
     } 

     if (Geolocation.isEnabled()) { 
      var location = Geolocation.getCurrentLocation({ 
       desiredAccuracy: 3, 
       updateDistance: 10, 
       maximumAge: 20000, 
       timeout: 20000 
      }) 
      .then(function(loc) { 
       if (loc) { 
        console.log("Current location is: " + loc["latitude"] + ", " + loc["longitude"]); 
        return Gmap.Position.positionFromLatLng(loc["latitude"], loc["longitude"]); 
       } 
      }, function(e){ 
       console.log("Error: " + e.message); 
      }); 

      if (location) 
       console.dir(location); 
     } 
    } 

    return viewModel; 
} 

module.exports = Map; 

回答

0

由於越來越位置是一個異步的過程,你應該viewModel.getCurrentPosition返回一個承諾,會看這樣的事情,

viewModel.getCurrentPosition() { 
    return new Promise((resolve, reject) => { 
     geolocation 
      .getCurrentLocation({ 
       desiredAccuracy: enums.Accuracy.high, 
       updateDistance: 0.1, 
       maximumAge: 5000, 
       timeout: 20000 
      }) 
      .then(r => { 
       resolve(r); 
      }) 
      .catch(e => { 
       reject(e); 
      }); 
    }); 
} 

,然後當你使用它,它看起來像這樣

defaultMapInfo.getCurrentPosition() 
    .then(latlng => { 
     // do something with latlng {latitude: 12.34, longitude: 56.78} 
    }.catch(error => { 
     // couldn't get location 
    } 
} 

希望幫助:)

更新:BTW,geolocation.enableLocationRequest()也是asynchorous方法。

+0

這就是我要找的,我的代碼現在非常簡單,謝謝XD – Sea

0

如果溼婆普拉薩德的註腳......

「geolocation.enableLocationRequest()也是asynchorous法」

...是正確的,那麼返回的承諾通過geolocation.enableLocationRequest()必須被處理適當的代碼將會發生相當大的變化。

試試這個:

viewModel.getCurrentPosition = function(options) { 
    var settings = Object.assign({ 
     'desiredAccuracy': 3, 
     'updateDistance': 10, 
     'maximumAge': 20000, 
     'timeout': 20000 
    }, options || {}); 

    var p = Promise.resolve() // Start promise chain with a resolved native Promise. 
    .then(function() { 
     if (!Geolocation.isEnabled()) { 
      return Geolocation.enableLocationRequest(); // return a Promise 
     } else { 
      // No need to return anything here. 
      // `undefined` will suffice at next step in the chain. 
     } 
    }) 
    .then(function() { 
     if (Geolocation.isEnabled()) { 
      return Geolocation.getCurrentLocation(settings); // return a Promise 
     } else { // <<< necessary to handle case where Geolocation didn't enable. 
      throw new Error('Geolocation could not be enabled'); 
     } 
    }) 
    .then(function(loc) { 
     if (loc) { 
      console.log("Current location is: " + loc.latitude + ", " + loc.longitude); 
      return Gmap.Position.positionFromLatLng(loc.latitude, loc.longitude); 
     } else { // <<< necessary to handle case where loc was not derived. 
      throw new Error('Geolocation enabled, but failed to derive current location'); 
     } 
    }) 
    .catch(function(e) { 
     console.error(e); 
     throw e; // Rethrow the error otherwise it is considered caught and the promise chain will continue down its success path. 
     // Alternatively, return a manually-coded default `loc` object. 
    }); 

    // Now race `p` against a timeout in case enableLocationRequest() hangs. 
    return Promise.race(p, new Promise(function(resolve, reject) { 
     setTimeout(function() { 
      reject(new Error('viewModel.getCurrentPosition() timed out')); 
     }, settings.timeout); 
    })); 
} 
return viewModel; 

注:

  1. 開始與解決本地無極鏈提供了多達包裝相同的效果new Promise(...)但清潔主要是因爲意想不到的內鏈拋出保證向鏈路的錯誤路徑下發一個Error對象,而不需要try/catch/reject()。此外,在標有「返回承諾」的兩行中,我們不必關心我們是否返回承諾或價值;要麼會被原生Promise鏈吸收。

  2. 兩個else條款是爲了迎合不會自動拋出的失敗案例。

  3. Promise.race()應該不是必要的,但是可以防止報告here的問題。有可能內置的「超時」機制就足夠了。這種額外的超時機制是一種「腰帶和大括號」措施。

  4. 包含一種機制,通過傳遞options對象來覆蓋viewModel.getCurrentPosition中的硬編碼默認值。要使用默認值運行,只需致電viewModel.getCurrentPosition()即可。此功能主要是爲了允許settings.timeoutPromise.race()中重複使用。

+0

Shiva Prasad的回答和你的工作像魅力一樣。我也更瞭解Promise並處理異步,非常感謝XD。 – Sea

+0

這兩個答案之間的差異將在故障條件下出現。例如。在禁用地理位置的設備上進行測試。 –

相關問題