循环保护
JS Bin的循环保护执行作为可再使用的库.
此代码保护用户代码包含一个使用 a 的无限循环的用户 while, (中文(简体) ), for 或者说 do 循环。 它还防止当一个React 组件本身引用时产生无限循环.
注意这一点 没有 解决 停止问题 但简单地重写了JavaScript(使用 Babel 的 AST) 以有条件的断开来包裹循环. 这个也是 没有 防止一般的循环循环,只是反应组件.
示例
随着循环保护的到位,这意味着用户可以在JS Bin上输入以下代码,以及最终的 console.log 还会继续工作.
代码从这里转换:
while (true) {
doSomething();
}
console.log('All finished');
...为了这个:
var _LP = Date.now();
while (true) {
if (Date.now() - _LP > 100)
break;
doSomething();
}
console.log('All finished');
使用量
循环保护是一种babel变换,因此可以用于服务器或客户端.
上一个执行使用一个被注入的库来处理跟踪回路 - 此版本没有.
实例(客户)实施
import Babel from 'babel-standalone';
import protect from 'loop-protect';
const timeout = 100; // defaults to 100ms
Babel.registerPlugin('loopProtection', protect(timeout));
const transform = source => Babel.transform(source, {
plugins: ['loopProtection'],
}).code;
// rewrite the user's JavaScript to protect loops
var processed = transform(getUserCode());
// run in an iframe, and expose the loopProtect variable under a new name
var iframe = getNewFrame();
// append the iframe to allow our code to run as soon as .close is called
document.body.appendChild(iframe);
// open the iframe and write the code to it
var win = iframe.contentWindow;
var doc = win.document;
doc.open();
doc.write('<script>' + processed + '<' + '/script>');
doc.close();
// code now runs, and if there's an infinite loop, it's cleanly exited
可选的第二个参数
在上述执行中,当由回路保护转换的代码包含无限回路时,回路会用一个回路清洁地退出 break 语句,循环后的任何代码通常都会被执行。 见 实例。 。 。 .
但如果你想登录一个错误到控制台以警告用户,或者扔出一个错误,以便在遇到无限循环时停止执行呢? 这个 protect 函数需要可选的第二个参数,可以处理两种行为.
-
要登录一个错误到控制台, 但循环后继续执行, 通过
protect字符串作为第二个参数。 当遇到无限回路时,此字符串将被登录console.error(),让用户知道他们的错误. -
要抛出错误并停止执行,通过
protect简单的回调函数,该函数会丢出新的错误。 注意,如果您使用line参数,您可以用一个模板字元来表示更具体的错误消息。 例如:
import Babel from 'babel-standalone';
import protect from 'loop-protect';
const callback = line => {
throw new Error(`Bad loop on line ${line}`);
};
const timeout = 100;
Babel.registerPlugin('loopProtection', protect(timeout, callback));
const transform = source => Babel.transform(source, {
plugins: ['loopProtection'],
}).code;
var processed = transform(getUserCode());
// do more stuff with processed code here
通过执行,将产生以下结果:
while (true) {
doSomething();
}
console.log('All finished'); // does not execute
// Error: Bad loop on line 1
可选的第三个参数
如果你的代码涉及一个大但有限的环数,你可以使用第三个
参数, iterations,提高性能. Date.now() 比较贵
操作,每次检查一次 iterations 穿过一圈.
与 iterations = 100 初始代码变为
var _LPC = 1;
var _LP = Date.now();
while (true) {
if (_LPC++ % 100 === 0 && Date.now() - _LP > 100)
break;
doSomething();
}
console.log('All finished');
跳过第一个 Date.now() 调用, 并仅检查是否循环
每100个路口跑一次太长了.