Как прервать использование метки с помощью setTimeout () - PullRequest
0 голосов
/ 22 мая 2018

Вот мой код:

mylabel:{
    var myTimeout = setTimeout(function(){
      SpinnerDialog.hide();
      alert("Timeout");
      break mylabel;
    }, 10000);
    connectWifi();
  }

У меня есть функция connectWifi(), которая может зависать, если сеть Wi-Fi недоступна, поэтому я хочу остановить ее через фиксированный промежуток времени.Эта функция содержит другие функции, она делает что-то вроде этого:

function(){
    function(){
      function(){

      }
    }
  }

Когда вызывается функция тайм-аута, я получаю сообщение об ошибке «Неопределенная метка»

РЕДАКТИРОВАТЬ: моя цель не остановитьфункция тайм-аута - остановка функции connectWifi.

, если вы хотите увидеть функцию connectWifi (), вот код (я использую следующие плагины Cordova: WifiManager, autowifi и CordovaMqTTPlugin):

    function connectWifi() {
  cordova.plugins.WifiManager.isWifiEnabled(function (err, wifiEnabled) {
    console.log("isWifiEnabled result : " + wifiEnabled);
    if (wifiEnabled == false) {
      cordova.plugins.WifiManager.setWifiEnabled(true, function (err, succes) { console.log(err, succes); });
      console.log("-- Wifi Enabled --");
    }
  });
  window.plugins.autowifi.setssid(s_SSID, s_PASS);
  SpinnerDialog.show(null, "Connexion en cours...", true);
  window.plugins.autowifi.connect(function (scc) {
    wifiReady = true;
    SpinnerDialog.hide();
    console.log("Wifi connected");
    console.log("debut fonction connectMQTT");
  if (wifiReady) {
    //Connexion MQTT
    SpinnerDialog.show(null, "Acces au serveur en cours...", true);
    cordova.plugins.CordovaMqTTPlugin.connect({
      url: _url, //a public broker used for testing purposes only. Try using a self hosted broker for production.
      port: _port,
      clientId: _clientId,
      success: function (s) {
        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);
        //Abonnement MQTT au topic
        cordova.plugins.CordovaMqTTPlugin.subscribe({
          topic: _topic,
          qos: 0,
          success: function (s) {
            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) {
              //params will be an empty object if topic pattern is NOT used. 
              document.getElementById("activity").innerHTML += "--> Payload for" + topic + " topic: " + JSON.stringify(payload) + "<br>"
            })
          },
          error: function (e) {
            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";
            //alert("err!! something is wrong. check the console")
            console.log(e);
          }
        });
        //---------------------

      },
      error: function (e) {
        SpinnerDialog.hide();
        connected = false;
        //document.getElementById('status').innerHTML = "déconnecté";
        //document.getElementById('statusbar').className = "w3-bar w3-red"
        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";
        alert("err!! something is wrong. check the console")
        console.log(e);
      },
      onConnectionLost: function (e) {
        SpinnerDialog.hide();
        console.log(JSON.stringify(e));
        connected = false;
        //document.getElementById('status').innerHTML = "déconnecté";
        //document.getElementById('statusbar').className = "w3-bar w3-red"
        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");
  }
  });
}

(Мало что на французском, потому что я француз)

Ответы [ 2 ]

0 голосов
/ 22 мая 2018

Вместо того, чтобы иметь огромный блок кода, давайте разделим его на небольшие многократно используемые многообещающие фрагменты:

function promisify(fn) {
  return function() {
    return new Promise((resolve, reject) => {
     fn((err, res) => err ? reject(err) : resolve(res));
    });
  }
}

const isWifiEnabled = promisify(cb =>  cordova.plugins.WifiManager.isWifiEnabled(cb));    

const enableWifi = promisify(cb => cordova.plugins.WifiManager.setWifiEnabled(true, cb));

const connect = options => promisify(cb => cordova.plugins.CordovaMqTTPlugin.connect({
  ...options,
  success: res => cb(null, res),
  error: cb,
})();

Теперь, когда мы получили обещания, мы можем легко их объединить в цепочку и работать с ними:

async function ensureWifi() {
  if(!await isWifiEnabled()) await enableWifi();
}

Чтобы реализовать тайм-аут, мы просто используем Promise.race:

function cancelAfter(promise, time) {
  const timeout = new Promise((_, reject) => setTimeout(reject, time, new Error("Timeout")));
  return Promise.race(promise, timeout);
}

Так что мы можем сделать:

(async function() {
  try {
    // show loaders here
    await cancelAfter(ensureWifi(), 1000);
    await cancelAfter(connect({ /*...*/ }), 200);
    // All done
 } catch(error) {
    // Api error or timeout
 }
})()
0 голосов
/ 22 мая 2018

break встречается в анонимной функции, которая объявлена ​​в помеченном операторе, но сама не является частью этого оператора.Вот почему вы не можете перейти к метке из анонимной функции.

Некоторые вопросы, которые обсуждают вашу реальную проблему (Как отменить действие из таймера):

Вы увидите, что на данный момент нет простого встроенного способа.

...