繁体   English   中英

如何在 JavaScript 中终止脚本?

[英]How to terminate the script in JavaScript?

我怎样才能像 PHP 的exitdie一样退出 JavaScript 脚本? 我知道这不是最好的编程实践,但我需要这样做。

“退出”函数通常会退出程序或脚本,并带有错误消息作为参数。 例如 php 中的 die(...)

die("sorry my fault, didn't mean to but now I am in byte nirvana")

JS 中的等价物是使用throw关键字发出错误信号,如下所示:

throw new Error();

您可以轻松测试:

var m = 100;
throw '';
var x = 100;

x
>>>undefined
m
>>>100

相当于 PHP 的die JavaScript 顺便说一句,它只是调用exit() (感谢 splattne):

function exit( status ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Brett Zamir (http://brettz9.blogspot.com)
    // +      input by: Paul
    // +   bugfixed by: Hyam Singer (http://www.impact-computing.com/)
    // +   improved by: Philip Peterson
    // +   bugfixed by: Brett Zamir (http://brettz9.blogspot.com)
    // %        note 1: Should be considered expirimental. Please comment on this function.
    // *     example 1: exit();
    // *     returns 1: null

    var i;

    if (typeof status === 'string') {
        alert(status);
    }

    window.addEventListener('error', function (e) {e.preventDefault();e.stopPropagation();}, false);

    var handlers = [
        'copy', 'cut', 'paste',
        'beforeunload', 'blur', 'change', 'click', 'contextmenu', 'dblclick', 'focus', 'keydown', 'keypress', 'keyup', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'resize', 'scroll',
        'DOMNodeInserted', 'DOMNodeRemoved', 'DOMNodeRemovedFromDocument', 'DOMNodeInsertedIntoDocument', 'DOMAttrModified', 'DOMCharacterDataModified', 'DOMElementNameChanged', 'DOMAttributeNameChanged', 'DOMActivate', 'DOMFocusIn', 'DOMFocusOut', 'online', 'offline', 'textInput',
        'abort', 'close', 'dragdrop', 'load', 'paint', 'reset', 'select', 'submit', 'unload'
    ];

    function stopPropagation (e) {
        e.stopPropagation();
        // e.preventDefault(); // Stop for the form controls, etc., too?
    }
    for (i=0; i < handlers.length; i++) {
        window.addEventListener(handlers[i], function (e) {stopPropagation(e);}, true);
    }

    if (window.stop) {
        window.stop();
    }

    throw '';
}

即使在没有句柄、事件等的简单程序中,最好将代码放在“主”函数中,即使它是唯一的过程:

<script> 
function main()
{
//code

}
main();
</script>

这样,当您想停止程序时,您可以使用“返回”。

如果你不在乎这是一个错误,只需写:

fail;

这将阻止您的主要(全局)代码继续进行。 对调试/测试的某些方面很有用。

很多方法可以退出 JS 或 Node 脚本。 以下是最相关的:

// This will never exit!
setInterval((function() {  
    return;
}), 5000);

// This will exit after 5 seconds, with signal 1
setTimeout((function() {  
    return process.exit(1);
}), 5000);

// This will also exit after 5 seconds, and print its (killed) PID
setTimeout((function() {  
    return process.kill(process.pid);
}), 5000);

// This will also exit after 5 seconds and create a core dump.
setTimeout((function() {  
    return process.abort();
}), 5000);

如果您在REPL 中(即在命令行上运行node之后),您可以键入.exit退出。

放置debugger; JavaScript 代码中要停止执行的关键字。 然后打开您最喜欢的浏览器的开发人员工具并重新加载页面。 现在它应该自动暂停。 打开工具的Sources部分: debugger; 关键字突出显示,您可以选择恢复脚本执行。

我希望它有帮助。

更多信息请访问:

就我而言,我使用了window.stop API,就像单击浏览器上的 X 按钮一样:

window.stop();

我想这个问题已经回答了,点击这里了解更多信息。 以下是它发布的简短答案。

throw new Error("Stop script");

您也可以使用浏览器添加断点,每个浏览器都相似,请查看以下浏览器信息。

有关 Chrome 断点信息,请单击此处
有关 Firefox 断点信息,请单击此处
对于 Explorer 断点信息,请单击
有关 Safari 断点信息,请单击此处

*注意-此信息有些过时,您可以在完成功能之前使用辅助线程或Web辅助线程在主线程之外尽早发送消息,基本上,您可以尽早返回所需的消息,然后从接收者中回想起。 您还可以执行类似(return(callchain(a,b,c,d))())的操作,或者只是将多个return嵌套在if语句中,然后打开一个标志以输入一个if语句,尽早执行return。 throw()可能会影响性能,并且我认为浏览器在编译时如果抛出异常,则无法正确优化代码。

话虽如此:该答案提供了利用throw()和添加的结构的详细信息,这些结构将有助于解决模块化javascript中的此问题和其他早期退出,异常,过程控制以及顺序函数处理的需求。 解决方案提供了关闭示例。 该答案假定该个人希望该脚本退出后,页面上的其他脚本继续运行。

喷笔演示: https : //codepen.io/alignedfibers/pen/VpMQzO

小提琴投掷演示: http : //jsfiddle.net/alignedfibers/cpe1o1yy/70/

<script>
    var safetyRun = (function(){
      var curExecution = null;
      var exceptionHandlers = {
        cleanup:function(){
          /*do exit cleanup*/
          console.log("Cleanup could set straglers to {}");
          return;
        }
      }
      var exitErr = function(errcode){
        curExecution.exNames.push("cleanup");
        throw new Error("EarlyExit");
      }
        var run = function(fun){
          curExecution = this;
          curExecution.exNames = [];
          fun(exitErr);
          for ( x in exNames){
            exceptionHandlers[x]();
          }
          return;
        }
        return run;
    })();
    var exitThisScript = function(exit){
      //write some modular code
      console.log("before exit");
      exit();
      console.log("after exit");
      return;
    }
    safetyRun(exitThisScript);
</script>

上面是一个“ CallRunner”,它提供了一种非常简单的方法,只需将函数传递给运行程序即可免费退出。

小提琴中的变量命名可能会引起混淆,名为“ fun”的函数是safetyRun中用于引用我们要退出的函数的名称,而exitErr是用于引用我们为实际完成退出而运行的函数的名称。 还有一点让人困惑的是:一旦exitErr完成,堆栈框架仍不会从调用我们退出的函数的控制线程中释放。 因为我们仍然具有控制线程,所以我们可以使用在exitErr函数中推到数组上的函数或错误代码,并在返回之前调用它们,以允许其他函数运行。 这使我们能够更改任何权重,进行更正或设置所需的任何状态,以用于警告需要注意的错误纠正状态,发送日志报告甚至完成具有挑战性的清理工作,并在后台自动修复该功能并自动调用exitErr直到它完成一个返回而不是抛出,从而使我们试图退出的功能提前完成(建议这样做是在offmainthread上完成)。 这种“包装器/线束”可能是在功能开始时验证浏览器版本和内容的好方法,如果您管理自己的库或您真正想到的东西,甚至可以在此处进行静态或动态导入。 退出仅是一项基本功能,可以通过将其包装起来而使其对您的功能可用。

小提琴中的代码有点脏而且不漂亮,新的es6构造可以使它更漂亮。 另外,我建议您在此函数的顶部调用线束生成器,并将其结果分配给本地var,以便要退出的函数看起来更像下面的代码。 为了在不释放堆栈的情况下保持控制线程,您仍将需要使用以下工具来包装您的香草函数,即需要使用arma.run(function(harness){/ MyVanillaFunc /}),否则理论上的以下内容应该可以工作。 包装正是我在上面的exitEarly代码中所做的。

var rockStarFunction = new function (){
var harness = reducePublicStrapOnFromCache()._url(location);
return function(){ /*wrapper would wrap these internals*/
        harness.scriptContextChangeEvent();
        harness.imInteligentFunction("{slib_err-15346 : 'Cannot handle request, ::suggest(mesh//abc) exit back to pool'}");
        harness.exit();
        console.log("You should never get this far");
        return true;
    };
}

如果您的意图是构建一个具有诸如exit,assert,mock等内置功能的javascript运行器容器,我在这里提供的解决方案是我推荐的一种。我认为这是构建此容器的最佳方法,可传输的功能。

扔 ””;

是对概念的误用,但可能是唯一的选择。 而且,是的,您将必须重置所有事件侦听器,就像提到的接受的答案一样。 如果我是对的,您还需要一个单一的入口点。

最重要的是:您需要一个页面,在它抛出后立即通过电子邮件向您报告-您可以为此使用例如 Raven/Sentry。 但这意味着,您会产生误报。 在这种情况下,您还需要更新默认处理程序以过滤掉此类事件或将此类事件设置为在 Sentry 的仪表板上忽略。

window.stop();

这在页面加载期间不起作用。 它也会停止对页面进行解码。 因此,您不能真正使用它来为用户提供页面的无 javascript 变体。

调试器;

仅在调试器打开时停止执行。 效果很好,但不是可交付成果。

如果您正在寻找一种方法来强制终止页面上所有 Javascript 的执行,我不确定是否有官方认可的方法来做到这一点 - 这似乎是一种可能存在安全风险的事情(尽管老实说,我想不出这会是怎么回事)。 通常在 Javascript 中,当您希望代码停止运行时,您只需从正在执行的任何函数return (如果return语句是函数中的最后一件事并且该函数不应该返回值,则它是可选的)如果有某种原因返回对您来说不够好,您可能应该在问题中编辑更多细节,以了解为什么认为您需要它,也许有人可以提供替代解决方案。

请注意,在实践中,如果遇到错误,大多数浏览器的 Javascript 解释器将简单地停止运行当前脚本。 因此,您可以执行诸如访问未设置变量的属性之类的操作:

function exit() {
    p.blah();
}

可能会中止脚本。 但是你不应该指望它,因为它根本不是标准的,而且它看起来真的是一种可怕的做法。

编辑:好的,根据 Ólafur 的说法,这可能不是一个很好的答案。 虽然他链接的die()函数基本上实现了我的第二段,即它只是抛出一个错误。

在 JavaScript 中有多种方式,下面是其中一些

方法一:

throw new Error("Something went badly wrong!");

方法二:

return;

方法三:

return false;

方法四:

new new

方法五:

使用上述方法编写自定义函数并在需要的地方调用

注意:如果您只想暂停代码执行,您可以使用

debugger; 

我知道这是旧的,但如果你想要一个类似的 PHP die()函数,你可以这样做:

function die(reason) {
    throw new Error(reason);
}

用法:

console.log("Hello");
die("Exiting script..."); // Kills script right here
console.log("World!");

上面的例子只会打印“Hello”。

总结不同的选项:

window.stop();
debugger;
for(;;);
window.location.reload();

如果页面已加载并且您不想调试崩溃或重新加载:

throw new Error();

另外清除所有超时

var id = window.setTimeout(function() {}, 0);
while (id--) {
    window.clearTimeout(id);
}

中止DOM/XMLHttpRequest

$.xhrPool = [];
$.xhrPool.abortAll = function() {
    $(this).each(function(i, jqXHR) { 
        jqXHR.abort();  
        $.xhrPool.splice(i, 1); 
    });
}
$.ajaxSetup({
    beforeSend: function(jqXHR) { $.xhrPool.push(jqXHR); },
    complete: function(jqXHR) {
        var i = $.xhrPool.indexOf(jqXHR);
        if (i > -1) $.xhrPool.splice(i, 1); 
    }
});

删除所有事件侦听器,包括内联

$("*").prop("onclick", null).off();

可能还有其他东西。 在评论中告诉我。

更新:由于你没有这个工作,只要catch了!

throw window.location.assign('dead.html');

这个小函数非常接近于模仿 PHP 的 exit()。 与其他解决方案一样,不要添加任何其他内容。

function exit(Msg)
    {
    Msg=Msg?'*** '+Msg:'';
    if (Msg) alert(Msg);
    throw new Error();
    } // exit

如果您在脚本中使用任何未定义的函数,则脚本将因“未捕获的 ReferenceError”而停止。 我尝试通过以下代码和前两行执行。

我认为,这是停止脚本的最佳方式。 如果有其他方法,请评论我。 我也想知道另一种最好的和简单的方法。 顺便说一句,我没有退出或死掉像 PHP 这样的 Javascript 中的内置函数来终止脚本。 如果有人知道,请告诉我。

alert('Hello');

document.write('Hello User!!!');

die();  //Uncaught ReferenceError: die is not defined

alert('bye');

document.write('Bye User!!!');

如果您只想停止执行更多代码而不“抛出”任何错误,您可以临时覆盖window.onerror ,如cross-exit所示:

function exit(code) {
    const prevOnError = window.onerror
    window.onerror = () => {
        window.onerror = prevOnError
        return true
    }

    throw new Error(`Script termination with code ${code || 0}.`)
}

console.log("This message is logged.");
exit();
console.log("This message isn't logged.");

我正在使用 iobroker 并轻松地设法停止脚本

stopScript();

此代码将停止执​​行当前窗口中的所有 JavaScript:

 for(;;);

例子

 console.log('READY!'); setTimeout(()=>{ /* animation call */ div.className = "anim"; console.log('SET!'); setTimeout(()=>{ setTimeout(()=>{ console.log('this code will never be executed'); },1000); console.log('GO!'); /* BOMB */ for(;;); console.log('this code will never be executed'); },1000); },1000);
 #div { position: fixed; height: 1rem; width: 1rem; left: 0rem; top: 0rem; transition: all 5s; background: red; } /* this <div> will never reached the right bottom corner */ #div.anim { left: calc(100vw - 1rem); top: calc(100vh - 1rem); }
 <div id="div"></div>

要在没有任何错误的情况下停止脚本执行,您可以将所有脚本包含在一个函数中并执行它。
下面是一个例子:

 (function () { console.log('one'); return; console.log('two'); })();

上面的脚本只会记录一个.

使用前

  • 如果您需要在脚本本身之外读取脚本的函数,请记住(通常)它不起作用:要做到这一点,您需要使用预先存在的变量或对象(您可以将您的函数放在窗口对象)。
  • 上面的代码可能是您不想要的:将整个脚本放在一个函数中可能会产生其他后果(例如,这样做,脚本将立即运行,并且在开发过程中无法从浏览器修改其部分,据我所知,在 Chrome 中)

在大多数情况下不适用,但我在浏览器中运行了很多异步脚本,并且作为一个 hack 我做了

window.reload();

停止一切。

这是一个示例,如果条件存在,则终止脚本。 我在我的 SSE 客户端 javascript 中使用它,如果

<script src="sse-clint.js" host="https://sse.host" query='["q1,"q2"]' ></script>

不能直接从 JSON 解析中解析...

if( ! SSE_HOST  ) throw new Error(['[!] SSE.js: ERR_NOHOST - finished !']);

......无论如何,总体思路是:

if( error==true) throw new Error([ 'You have This error' ,  'At this file', 'At this line'  ]);

这将终止/终止您的 javasript 脚本

只需创建一个 BOOL 条件,这里不需要复杂的代码..

如果即使您将其变为真/或多次,它也会为您提供一行解决方案/而不是多个解决方案-基本上就这么简单。

我使用这段代码来停止执行:

throw new FatalError("!! Stop JS !!");

虽然你会收到一个控制台错误,但它对我很有用。

如何像PHP的exitdie那样退出JavaScript脚本? 我知道这不是最佳编程实践,但我需要这样做。

我使用 return 语句而不是 throw 因为 throw 在控制台中给出错误。 最好的方法是检查条件

if(condition){
 return //whatever you want to return
}

这只是停止从该行执行程序,而不是在控制台中给出任何错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM