手记

如何终止 JS 脚本的运行

在很多其他语言比如 PHP 当中,存在 exit 函数来中止程序的运行。很遗憾的是 JavaScript 没有。因此我们需要自己模拟出这么一个 “exit” 功能。
我们知道,break是 JavaScript 中合法的中断语句,但其只适用于循环和 switch 语句,此路不通。除了 break,JavaScript 还可以通过 return 来显示终止一个函数的执行,比如:

function foo(){
console.log('executed');
return;
console.log('not executed');
}
return 语句之后的代码将不会被执行。看起来可以用这个方式来达到我们终止 JS 脚本运行的目的。

那么我们来试试看在脚本中使用 return:

// index.js
console.log("OK,let's start");
console.log('first step');
console.log('second step');
return;
console.log('you cannot see me');
我们把脚本丢到浏览器里去执行一下,发现报错了,信息如下:

Uncaught SyntaxError: Illegal return statement
这里我们犯了一个严重的错误:return 只能应用于函数内部,而脚本本身并不是函数。这里大家可能很自然的想到,把脚本包裹在一个自执行匿名函数(IIFE)里不就行了。我们尝试一下:

// index.js
;(function() {
console.log("OK,let's start");
console.log('first step');
console.log('second step');
return;
console.log('you cannot see me');
})();
浏览器的执行结果如下:

OK,let's start
first step
second step
OK,我们的目标达成,成功终止了脚本的运行。确实,将代码包裹在 IIFE 中可以随时控制脚本运行是否终止,但是这是否有点麻烦呢?固然我们有 Rollup 一类的工具可以将代码打包成为 IIFE 形式,但毕竟多一步操作,还需要对构建工具进行配置,在小项目里成本过高。而且,并不是所有需要中断程序运行的场景下都适合将代码通过 IIFE 来执行。因此,这一方式可行,但不够简洁。

实际可行的方法是利用错误来终止 JavaScript 程序的运行。这里的错误包括语法错误、变量错误、程序错误等等,我们只需要用 throw new Error() 的方式抛出错误,就能达到目的。在抛出该错误之前的代码可正常执行不受影响,而在其之后的代码则不会执行。看下例子:

// index.js
console.log("OK,let's start");
console.log('first step');
console.log('second step');
throw new Error('this is my customed error');
console.log('you cannot see me');
结果如下:

OK,目标达成。你可以在你的程序中任意想中止的地方抛出错误,然后就能达到 exit 的目的。

但是,进一步思考,为什么 JavaScript 没有提供类似其他语言的 exit 函数呢?实际上,这一切都是因为 JavaScript 是单线程语言,基于代码可以异步执行的考虑,才没有设置 exit 功能。那么,是不是在包含异步执行的代码中,我们的抛出错误的方法实际上也不能立刻终止程序呢?答案是肯定的,我们看下例子:

// index.js
console.log("OK,let's start");
console.log('first step');
console.log('second step');
setTimeout(() => {
console.log('you still can see me');
}, 1000);
throw new Error('this is my customed error');
console.log('you cannot see me');
执行结果如下:

“you still can see me” 延迟了一秒输出,但是仍然输出了,说明我们的 throw new Error 并没有立刻中止异步代码的执行。实际上这也是必然的,感兴趣的同学可以去研究一下 JavaScript 的运行机制以及 Event Loop 相关的内容。

最后,我们得出结论,JavaScript 的主线程同步任务可以通过抛出错误的方式立即中止,但是异步任务并不会受到影响。

1人推荐
随时随地看视频
慕课网APP