在Javascript中创建异步函数

时间:2013-10-18 12:46:19

标签: javascript asynchronous

我有这个模块包含对异步方法的调用,以监视浏览器地理位置的变化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函数尝试使其异步,但它不起作用。

请不要错过任何帮助。

3 个答案:

答案 0 :(得分: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)
       }
   };
});

答案 1 :(得分: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;
        }
   };
});

答案 2 :(得分: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);
  }
}