Срок выполнения кода - PullRequest
0 голосов
/ 12 мая 2018

Учитывая следующее выполнение JS-программы в JS-расчете, как я могу реализовать ограничение по времени для предотвращения бесконечных циклов в program?

try {
  var x = eval(document.getElementById("program").value);
} catch(e) {
  ...
}

Примечание: вызов должен иметь возможность указыватьмаксимальное время выполнения, на случай, если program входит в бесконечный цикл.

1 Ответ

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

Вы можете использовать веб-работника для запуска этого в другом потоке:

// Worker-helper.js
self.onmessage = function(e) {
  self.postMessage(eval(e.data));
};

. Они используют работника как:

var worker = new Worker('Worker-helper.js');
worker.postMessage(document.getElementById("program").value);

worker.onmessage = result => {
  alert(result);
};

setTimeout(() => worker.terminate(), 10 * 1000);

..., который убьет работника через 10 секунд.


Простая в использовании утилита:

function funToWorker(fn) {
  var response = "(" + fn.toString() + ")()";
  var blob;
  try {
    blob = new Blob([response], {type:  'application/javascript'});
   } catch (e) { // Backwards-compatibility
     window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;
     blob = new BlobBuilder();
     blob.append(response);
    blob = blob.getBlob();
   }

   return new Worker(URL.createObjectURL(blob));
 }

 function limitedEval(string, timeout) {
   return new Promise((resolve, reject) => {
     const worker = funToWorker(function() {
        self.onmessage = e => {
          self.postMessage(eval(e.data));
        }
     });

     worker.onmessage = e => resolve(e.data);
     worker.postMessage(string);
    setTimeout(() => {
       worker.terminate();
       reject();
    }, timeout);
  });
}

Используется как:

 limitedEval("1 + 2", 1000)
    .then(console.log)
    .catch(console.error);

Попробуйте!

...