前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >漫谈如何终止 JS 程序的运行

漫谈如何终止 JS 程序的运行

作者头像
逆葵
发布2019-04-25 11:13:51
7.5K0
发布2019-04-25 11:13:51
举报
文章被收录于专栏:FECodingFECoding

最近在开发一个 JSSDK 的时候有一个需求:为了检测当前环境中是否已经加载过该脚本,需要在脚本开始运行时加入一层判断,如果检测到已存在该脚本导出的变量,则终止脚本的后续运行,否则再执行后续逻辑。 那么便碰上了本文标题的问题:如何终止 JS 程序的运行?

在很多其他语言比如 PHP 当中,存在 exit 函数来中止程序的运行。很遗憾的是 JavaScript 没有。因此我们需要自己模拟出这么一个 “exit” 功能。

我们知道,break是 JavaScript 中合法的中断语句,但其只适用于循环和 switch 语句,此路不通。除了 break,JavaScript 还可以通过 return 来显示终止一个函数的执行,比如:

代码语言:javascript
复制
function foo(){
  console.log('executed');
  return;
  console.log('not executed');
}

return 语句之后的代码将不会被执行。看起来可以用这个方式来达到我们终止 JS 脚本运行的目的。

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

代码语言:javascript
复制
// index.js

console.log("OK,let's start");
console.log('first step');
console.log('second step');
return;
console.log('you cannot see me');

我们把脚本丢到浏览器里去执行一下,发现报错了,信息如下:

代码语言:javascript
复制
Uncaught SyntaxError: Illegal return statement

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

代码语言:javascript
复制
// index.js

;(function() {
  console.log("OK,let's start");
  console.log('first step');
  console.log('second step');
  return;
  console.log('you cannot see me');

})();

浏览器的执行结果如下:

代码语言:javascript
复制
OK,let's start
first step
second step

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

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

代码语言:javascript
复制
// 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 功能。那么,是不是在包含异步执行的代码中,我们的抛出错误的方法实际上也不能立刻终止程序呢?答案是肯定的,我们看下例子:

代码语言:javascript
复制
// 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 的主线程同步任务可以通过抛出错误的方式立即中止,但是异步任务并不会受到影响。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档