javascript中停止程序执行实现exit效果

javascript中非常坑的一点是,所以的代码几乎都为异步执行做了准备,虽然在很多时候这样做确实很方便,但是有的时候却坑了开发者。在javascript中有一个很疼的问题,就是没有办法退出程序,也就是其他很多语言中都有的exit命令操作。

不过,为了填平这个坑,我们也要想很多办法来做到这个效果。

为什么非得要在javascript中中断执行呢?举一个例子:

document.getElementById('btn').onclick = function(){
    Dialog.open(function(result){
        if(result.error == 1) Dialog.stop();
    });
}

这段代码的意思是,当点击#btn时,Dialog插件进行打开操作,但是在打开过程中,通过result的判断,决定是否继续打开,还是停止退出。

要实现Dialog.stop()必须进到Dialog插件的内部,对插件源码进行调整,如果从面向对象的角度讲,我们不应该对插件本身进行修改,而是通过外部的行为在有限的接口中做可能做的事。而这个时候问题就来了,如果插件执行Dialog.stop()操作是在打开dialog之后呢?也就是说我们本来希望error == 1的时候不要弹出弹窗,可是实际上,因为open()方法的回调函数是在弹窗打开时同时执行的,所以这就导致弹窗一定会打开。我们可以看下Dialog的这个位置的源码:

Dialog.open = function(callback){
...
if(typeof callback == 'function') callback(result);
show(element_id,content);
...
}

虽然在源码中,callback在show之前执行,但是我们无法做到在执行到callback时禁止下方的show()执行。在javascript中,唯一合法的中断语句包括break和return,前这用在for和switch中,后者用在function中,但是没有任何一个方法,可以让上述代码中的callback(result)可以停止代码执行。

那么下面是放出黑科技的时候了。

在javascript中,停止,或者避免当前代码以下的代码被执行的,可以使用错误来实现。这里的错误包括语法错误、程序错误、变量错误,甚至内存溢出。比方说,我们回到上面第一段代码,我们用红色标记出了Dialog.stop(),可是实际上,在Dialog插件中,并不存在这样一个方法,在全局中也不存在一个stop()函数,所以,这里会出现一个错误:

function stop is not defined!

而当错误出现的时候,javascript停止执行。这种方法可能影响系统中的其他代码的执行。而如果我们希望通过一种比较合法化的方法达到同样的效果,则可以使用throw来做到:

throw new Error(result.error_code);

当javascript遇到throw new Error时,会抛出错误,它可以立即终止整个javascript代码的运行。当然,在它之前运行过的代码,是ok的,并不会受到过大的影响,甚至在它之后的函数,也能被正常调用:

a(1);

throw new Error('exit');

a(2);

function a(msg) {
 alert(msg);
}

上面这段代码中,a(1)被正常执行,而a(2)则不行。(当然,通过调用一个错误的函数,也可以达到这个效果。)

2016-03-08