You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用setTimeout结合label中断connectWifi函数时出现未定义标签错误

问题分析与解决方案

首先,你遇到的Undefined label错误原因很明确:setTimeout的回调函数是异步执行的,它运行在一个独立的作用域里,没办法访问到外层的mylabel标签。而且就算能访问,break也只能用来跳出循环或switch语句,根本没法终止像connectWifi这种包含多层异步回调的函数执行。

要实现“超时后终止connectWifi的执行逻辑”,我们需要通过状态标记+中断异步回调链的方式来处理——因为你用到的Cordova插件大多是异步操作,没法直接强制终止函数,只能让后续的回调逻辑不再执行。

具体实现步骤

1. 新增超时状态标记

我们需要一个变量来记录是否发生了超时,这个变量要能被setTimeout回调和connectWifi的所有嵌套回调访问到(这里用闭包包裹,避免全局变量污染)。

2. 修改超时触发逻辑

在超时回调里,标记超时状态、清理UI,并尝试取消可能的插件操作(如果插件支持的话),同时清除定时器避免重复触发。

3. 在connectWifi的所有异步回调中检查超时状态

每一步异步操作完成后,先判断是否已经超时,如果是,就直接返回,不执行后续的逻辑。

修改后的完整代码示例

// 用闭包包裹,避免全局变量污染
(function() {
  let isTimeoutOccurred = false; // 超时状态标记

  function startWifiConnection() {
    isTimeoutOccurred = false; // 重置超时标记
    const connectionTimeout = setTimeout(function() {
      isTimeoutOccurred = true;
      SpinnerDialog.hide();
      alert("Timeout");
      // 若插件支持取消操作,可在此调用(需查阅插件文档)
      // 例如autowifi如果有cancelConnect方法:
      // if (window.plugins.autowifi.cancelConnect) window.plugins.autowifi.cancelConnect();
    }, 10000);

    connectWifi(function() {
      // 连接流程结束(成功/失败/超时)后清除定时器
      clearTimeout(connectionTimeout);
    });
  }

  function connectWifi(onFinish) {
    // 第一步:检查WiFi是否开启
    cordova.plugins.WifiManager.isWifiEnabled(function (err, wifiEnabled) {
      if (isTimeoutOccurred) return onFinish(); // 超时则终止后续逻辑
      console.log("isWifiEnabled result : " + wifiEnabled);
      if (!wifiEnabled) {
        cordova.plugins.WifiManager.setWifiEnabled(true, function (err, succes) {
          if (isTimeoutOccurred) return onFinish();
          console.log(err, succes);
        });
        console.log("-- Wifi Enabled --");
      }

      // 设置SSID和密码
      window.plugins.autowifi.setssid(s_SSID, s_PASS);
      SpinnerDialog.show(null, "Connexion en cours...", true);

      // 连接WiFi
      window.plugins.autowifi.connect(function (scc) {
        if (isTimeoutOccurred) return onFinish();
        wifiReady = true;
        SpinnerDialog.hide();
        console.log("Wifi connected");
        console.log("debut fonction connectMQTT");

        if (wifiReady) {
          // 连接MQTT
          SpinnerDialog.show(null, "Acces au serveur en cours...", true);
          cordova.plugins.CordovaMqTTPlugin.connect({
            url: _url,
            port: _port,
            clientId: _clientId,
            success: function (s) {
              if (isTimeoutOccurred) return onFinish();
              alert("Connexion reussie !");
              connected = true;
              console.log(JSON.stringify(s));
              document.getElementById("connect").style.display = "none";
              document.getElementById("disconnect").style.display = "initial";
              document.getElementById("activity").innerHTML += "--> Success: you are connected to, " + _url + ":" + _port + "<br>";
              SpinnerDialog.hide();
              SpinnerDialog.show(null, "Recuperation des donnees...", true);

              // 订阅MQTT主题
              cordova.plugins.CordovaMqTTPlugin.subscribe({
                topic: _topic,
                qos: 0,
                success: function (s) {
                  if (isTimeoutOccurred) return onFinish();
                  SpinnerDialog.hide();
                  document.getElementById("activity").innerHTML += "--> Success: you are subscribed to the topic, " + _topic + "<br>";
                  cordova.plugins.CordovaMqTTPlugin.listen(_topic, function (payload, params, topic, topic_pattern) {
                    if (isTimeoutOccurred) return;
                    document.getElementById("activity").innerHTML += "--> Payload for" + topic + " topic: " + JSON.stringify(payload) + "<br>";
                  });
                },
                error: function (e) {
                  if (isTimeoutOccurred) return onFinish();
                  SpinnerDialog.hide();
                  document.getElementById("activity").innerHTML += "--> Error: something is wrong when subscribing to this topic, " + e + "<br>";
                  document.getElementById("subscribe").style.display = "initial";
                  document.getElementById("unsubscribe").style.display = "none";
                  console.log(e);
                }
              });
            },
            error: function (e) {
              if (isTimeoutOccurred) return onFinish();
              SpinnerDialog.hide();
              connected = false;
              alert("Echec de la connexion, assurez-vous que vous êtes connectés en wifi au serveur puis veuillez reessayer");
              document.getElementById("activity").innerHTML += "--> Error: something is wrong,\n " + JSON.stringify(e) + "<br>";
              document.getElementById("connect").style.display = "initial";
              document.getElementById("disconnect").style.display = "none";
              console.log(e);
            },
            onConnectionLost: function (e) {
              if (isTimeoutOccurred) return onFinish();
              SpinnerDialog.hide();
              console.log(JSON.stringify(e));
              connected = false;
              alert("Vous avez ete deconnecte");
              document.getElementById("activity").innerHTML += "--> You got disconnected";
              document.getElementById("connect").style.display = "initial";
              document.getElementById("disconnect").style.display = "none";
            }
          });
        } else {
          console.log("wifiReady false");
        }
        onFinish();
      });
    });
  }

  // 调用此函数启动WiFi连接流程
  // startWifiConnection();
})();

额外说明

  • 我添加了onFinish回调,用来在连接流程结束(成功/失败/超时)时清除定时器,避免定时器重复触发。
  • 重点:如果你的Cordova插件(比如autowifi、CordovaMqTTPlugin)提供了取消异步操作的API,一定要在超时回调里调用它——这样能真正中断插件的底层操作,而不仅仅是停止后续的JS逻辑,你需要查阅插件官方文档确认。
  • 所有异步回调的开头都加入了超时状态检查,确保超时后不会继续执行后续业务逻辑。

内容的提问来源于stack exchange,提问作者Alban .L

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:26:25