【问题标题】:How to use SetTimeout correctly (typescript)如何正确使用 SetTimeout(打字稿)
【发布时间】:2017-08-14 22:20:51
【问题描述】:

我正在开发一个使用 Geolocation 的 ionic-cordova 应用程序。

根据应用流程需要获取准确的位置。

我编写了专门的方法来实现定位,并在其中使用了setTimeout

根据我的日志,我似乎没有正确使用setTimeout - 甚至最糟糕的是我选择不当,setTimeout 不是我需要的。

这是我的代码:

  getFixedLocation() {
    let coordinates: Coordinates;
    let maxTries = 15;
    let isFixedLocation = false;

    this.forceFixLocation(10);

    do {
      console.log("Getting location, try #" + maxTries)
      this.geolocation.getCurrentPosition(GEOLOCATION_OPTIONS)
      .then((position) => {
        coordinates = position.coords;
      });

      if (coordinates.accuracy < 25 && coordinates.speed < 1) {
        isFixedLocation = true;
      } else {
        maxTries -= 1;
      }
    } while(maxTries > 0 && !isFixedLocation);

    if (isFixedLocation) {
      return coordinates;
    } else {
      return null;
    }
  }

  forceFixLocation(counter: number) {
    setTimeout(() => {
      if(counter > 0) {
        console.log("Forcing location #" + counter)        
        this.geolocation.getCurrentPosition(GEOLOCATION_OPTIONS)
        .then((position) => {
          console.log("Got position, accuracy: " + position.coords.accuracy)
        }); 
        this.forceFixLocation(counter - 1);
      }
    }, 3000);
  }

查看日志显示我的do-while 循环在forceFixLocation 的第一次迭代之前执行:

08-15 00:58:51.831 D/SystemWebChromeClient(19622): file:///android_asset/www/build/main.js: Line 56358 : Getting location, try #15
08-15 00:58:51.831 I/chromium(19622): [INFO:CONSOLE(56358)] "Getting location, try #15", source: file:///android_asset/www/build/main.js (56358)
08-15 00:58:51.831 D/GeolocationPlugin(19622): We are entering execute
08-15 00:58:51.841 D/SystemWebChromeClient(19622): file:///android_asset/www/build/main.js: Line 1362 : ERROR
08-15 00:58:51.841 I/chromium(19622): [INFO:CONSOLE(1362)] "ERROR", source: file:///android_asset/www/build/main.js (1362)
08-15 00:58:54.834 D/SystemWebChromeClient(19622): file:///android_asset/www/build/main.js: Line 56381 : Forcing location #10
08-15 00:58:54.844 I/chromium(19622): [INFO:CONSOLE(56381)] "Forcing location #10", source: file:///android_asset/www/build/main.js (56381)
08-15 00:58:54.844 D/GeolocationPlugin(19622): We are entering execute
08-15 00:58:56.936 D/SystemWebChromeClient(19622): file:///android_asset/www/build/main.js: Line 1362 : ERROR
08-15 00:58:56.946 I/chromium(19622): [INFO:CONSOLE(1362)] "ERROR", source: file:///android_asset/www/build/main.js (1362)
08-15 00:58:57.847 D/SystemWebChromeClient(19622): file:///android_asset/www/build/main.js: Line 56381 : Forcing location #9
08-15 00:58:57.847 I/chromium(19622): [INFO:CONSOLE(56381)] "Forcing location #9", source: file:///android_asset/www/build/main.js (56381)

这里的正确方法是什么?

【问题讨论】:

    标签: javascript typescript settimeout


    【解决方案1】:

    forceFixLocation 内部的 lambda 函数将在 3 秒后第一次调用。当您从getFixedLocation 调用this.forceFixLocation(10); 时,它会立即继续下一行并执行while 的逻辑。 不仅如此,getFixedLocation 可能已经返回了一些值,但您仍然会每 3 秒(10 次)调用一次 forceFixLocation

    【讨论】:

    • 我了解当前代码会发生什么。问题是如何修改它,以便只有在对 forceFixLocation 的所有十次调用都返回后才会执行 do-while 逻辑。
    • 将 do - while 逻辑提取到单独的函数中并从 forceFixLocation 中调用它。
    【解决方案2】:

    您在这里缺少基本信息。这就是 JavaScript 事件循环!

    您不能使用do while,因为它永远不会(永远)结束,并且会挂起您的应用程序,如日志所示。

    看起来你并没有等待承诺解决。承诺提供的then 方法只是一个可能/将在未来发生的功能。您的 do/while 挂起应用程序,因此它无法解决此承诺...

    我建议尝试 async/await,因为它提供的语法与您期望从 JavaScript 中获得的语​​法相似。

    【讨论】:

    • 谢谢。你能帮我解决这个问题吗?我阅读了有关 async/await 的信息,但我不确定如何将 do while 逻辑修改为 async/await。
    • 我不确定你想要实现的逻辑是什么......我最好打开一个关于如何将代码转换为 async/await 的新问题
    猜你喜欢
    • 2021-12-21
    • 2019-03-21
    • 1970-01-01
    • 2021-09-28
    • 2019-03-27
    • 2017-10-25
    • 2020-04-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多