Убить все запущенные функции JavaScript по клику - PullRequest
0 голосов
/ 03 мая 2018

Это расширение моего предыдущего вопроса, в основном из любопытства: Убить все запущенные функции JavaScript с тайм-аутами при клике

У меня есть веб-страница с 3 кнопками и разделом «результата»:

<button id="b1" onclick="f1()">1st button</button>
<button id="b2" onclick="f2()">2nd button</button>
<button id="b3" onclick="f3()">3rd button</button>
<p id="result">"Here will be the result!"</p>

Вот фрагменты для функций JavaScript. Я также использовал веб-работника:

// The functions are similar, but the outputs are different

var worker;

function calcF1() {
    var answer;
    for (let i = 0; i < 1e9; i++) {
        // Do some complicated calculations
    }
    postMessage(answer);
}

function f1() {
    // TODO: Kill other running instances of all functions

    // Calling worker
    var cf1 = calcF1.toString();
    var code = cf1.substring(cf1.indexOf('{')+1, cf1.lastIndexOf('}'));
    var blob = new Blob([code], {type: 'application/javascript'});
    worker = new Worker(URL.createObjectURL(blob));

    worker.onmessage = message => {
        document.getElementById("result").innerHTML = "1st function";
    };
}

function calcF2() {
    var answer;
    for (let i = 0; i < 1e9; i++) {
        // Do some complicated calculations
    }
    postMessage(answer);
}

function f2() {
    // TODO: Kill other running instances of all functions

    // Calling worker
    var cf2 = calcF2.toString();
    var code = cf2.substring(cf2.indexOf('{')+1, cf2.lastIndexOf('}'));
    var blob = new Blob([code], {type: 'application/javascript'});
    worker = new Worker(URL.createObjectURL(blob));

    worker.onmessage = message => {
        document.getElementById("result").innerHTML = "2nd function";
    };
}

function calcF3() {
    var answer;
    for (let i = 0; i < 1e9; i++) {
        // Do some complicated calculations
    }
    postMessage(answer);
}

function f3() {
    // TODO: Kill other running instances of all functions

    // Calling worker
    var cf3 = calcF3.toString();
    var code = cf3.substring(cf3.indexOf('{')+1, cf3.lastIndexOf('}'));
    var blob = new Blob([code], {type: 'application/javascript'});
    worker = new Worker(URL.createObjectURL(blob));

    worker.onmessage = message => {
        document.getElementById("result").innerHTML = "3rd function";
    };
}

Однако, если пользователь нажимает b1, а затем сразу же нажимает b2, рабочий с помощью f1 не прекратит работу и продолжит работу. Если рабочий из f1 заканчивает работу до этого из f2, то result покажет 1st function и затем будет заменен на 2nd function. Также существует вероятность того, что рабочий на f2 сначала финиширует, и в этом случае result покажет 2nd function, а затем будет заменен на 1st function.

Я хочу реализовать в начале каждой функции оператор, который убивает / игнорирует / обходит все функции и / или всех веб-работников, которые работают в данный момент, так что конечный результат всегда будет связан с последняя кнопка, которую нажал пользователь. Как это может быть лучше всего реализовано?

РЕДАКТИРОВАТЬ: Спасибо за указание веб-работника. Мои оригинальные реализации были связаны с веб-работниками, но я забыл упомянуть Вопрос был обновлен.

1 Ответ

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

Разделите функции таким образом, чтобы они выполнялись только в течение умеренного периода времени, прежде чем остановить и перенести следующий запуск в конец стека с помощью setTimeout, чтобы другие функции могли запускаться. В начале каждого f1, f2 и f3 проверьте, имеют ли они уникальную ссылку на ключ текущей выполняемой функции, и вернитесь, если они этого не делают.

В следующем фрагменте текущая функция f1 переопределяется более поздним вызовом f2:

let runningFunctionKey;
function f1(key, start = 0) {
  if (!key) {
    runningFunctionKey = {}; // some unique reference
    key = runningFunctionKey;
  } else if (key !== runningFunctionKey) return;
  const until = start + 1e7;
  while (start < until) {
    if (start === 1e9) {
      console.log('f1 done');
      return;
    }
    start++;
  }
  console.log('f1 setting timeout');
  setTimeout(f1, 0, key, start);
}
function f2(key, start = 0) {
  if (!key) {
    runningFunctionKey = {}; // some unique reference
    key = runningFunctionKey;
  } else if (key !== runningFunctionKey) return;
  const until = start + 1e7;
  while (start < until) {
    if (start === 1e9) {
      console.log('f2 done');
      return;
    }
    start++;
  }
  console.log('f2 setting timeout');
  setTimeout(f2, 0, key, start);
}
f1();
setTimeout(f2, 500);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...