0

我有这个模块,它包装了对异步方法的调用,以观察浏览器地理位置的变化navigator.geolocation.watchPosition

var geo_value;

//Initialises the devices geolocation
navigator.geolocation.watchPosition(function (position) {
    geo_value = position.coords.longitude + "," + position.coords.latitude;
});

每次watchPosition方法调用触发时,我都会将值存储在一个变量中,以便currentPosition在任何给定时间为我提供对 的编程访问。

这一切都很好,但是我现在想currentPosition通过我从模块中导出的自定义异步方法来公开它。

define(["global"], function (window) {

   var navigator = window.navigator;

   var geo_value;

   //Initialises the devices geolocation
   navigator.geolocation.watchPosition(function (position) {
       geo_value = position.coords.longitude + "," + position.coords.latitude;
   });


   return {
       currentPosition: function (callback) {
           setTimeout(function () {
               while (!geo_value) {
                   //keep looping until geo_value has been initially set by the watch position above
               }
               //geo_value has been set, execute callback
               callback(geo_value);
           }, 0);

       }
   };
});

我已经module公开了currentPosition,如果geo_value已经设置了它就可以工作,但我也希望它在geo_value尚未设置的情况下异步等待,然后在watchPosition最终设置geo_value. 我尝试使用该setTimeout函数尝试使其异步,但它不起作用。

请任何帮助将不胜感激。

4

3 回答 3

2

因此,Javascript 实际上是一个单线程事件循环。了解这究竟意味着什么需要经验。

在这种情况下,这意味着您的 while 循环将永远不会终止,因为在它运行时不会发生任何其他事情。

一种更好的方法是在调用 watchPosition 时将您获得的回调作为 currentPosition 的参数调用。

define(["global"], function (window) {

   var navigator = window.navigator,
       geo_value,
       callbacks = [],


   //Initialises the devices geolocation
   navigator.geolocation.watchPosition(function (position) {
       geo_value = position.coords.longitude + "," + position.coords.latitude;

       // Update all callbacks with new value. 
       for (var i = 0; i < callbacks.length; i++) {
           callbacks[i](geo_value);
       }
   });


   return {
       onCurrentPosition: function (callback) {
           callbacks.push(callback)
       }
   };
});
于 2013-10-18T12:52:44.313 回答
1
define(["global"], function (window) {

   var navigator = window.navigator;

   var geo_value;
   var cb;

   //Initialises the devices geolocation
   navigator.geolocation.watchPosition(function (position) {
       geo_value = position.coords.longitude + "," + position.coords.latitude;
       if (cb) {
         cb(geo_value);
         cb = null;
       }
   });


   return {
       currentPosition: function (callback) {
        if (geo_value) {
            callback(geo_value);
        } else {
            cb = callback;
        }
   };
});
于 2013-10-18T12:51:40.357 回答
0

下面的代码阻止了其他代码被执行,因为 JavaScript 只有一个执行线程:

while (!geo_value) {
    //keep looping until geo_value has been initially set by the watch position above
}

而是尝试这样的事情:

currentPosition: function(callback) {
  if (geo_value) {
    callback(geo_value);
  } else {
    // try again 1 sec later
    setTimeout(this.currentPosition.bind(this, callback), 1000);
  }
}
于 2013-10-18T12:54:26.873 回答