代码执行的时间限制

时间:2018-05-12 12:09:37

标签: javascript eval infinite-loop

考虑到JS解决方案中的以下JS程序的执行,如何实现时间限制以防止program中的无限循环?

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

注意:调用应该能够指定最长执行时间,以防program进入无限循环。

1 个答案:

答案 0 :(得分:1)

你可以使用webworker在另一个线程中运行它:

// 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);

Try it!