【问题标题】:How do you exit the caller function in JavaScript?你如何退出 JavaScript 中的调用者函数?
【发布时间】:2013-03-28 09:52:17
【问题描述】:

是否可以从 JavaScript 中的调用函数返回/退出?

我们正在向我们的框架添加测试方法,如果断言出现错误,我们希望退出。

鉴于以下简单的示例代码,我想用 EXIT_TEST_THAT_CALLED_ME 交换将退出(相当于在测试中返回)方法 Test123 的东西。

Assert = function ( expectedTrue, comment ) {
    if( ! expectedTrue ) {
      Log.Error( comment );
      EXIT_TEST_THAT_CALLED_ME;    
    }
}

Test123 ( ... ) {

  var inputField = getInputField(".input");
  Assert( (inputField !== null ), "Checking that we found an input field");

  inputField.doSomething();
  // This row will cause run time error if inputField is null  

}

我尝试过的
返回 - 当然不起作用,因为它只从断言方法返回
arguments.callee.caller。 return - 什么都不做
arguments.callee.caller.return() - 没有方法'return'

注意
更改为已经具有此功能并且一切都很好的测试框架不是一种选择。 :(

【问题讨论】:

  • 你为什么不通过异常?
  • @javapirate 这就是我最终所做的。似乎是最好的办法。 Tnx

标签: javascript language-features


【解决方案1】:

一种选择是使用try\catch\throw

Assert = function ( expectedTrue, comment ) {
    if( ! expectedTrue ) {
      Log.Error( comment );
      throw "OOPS";
    }
}

try{
  // function that users Assert
  Test123 ( ... )
}

catch(err){       
    alert(err);
    if (err=="OOPS"){
    //special handling for a certain exception
    }
}

使用这个流程,当异常被抛出的那一刻,它会向上传播,直到它到达你处理异常的catch块。

此外,异常不仅限于字符串。它可以是整数、布尔值或对象。

【讨论】:

  • 抛出异常似乎是正确的做法。谢谢
【解决方案2】:

无法更改调用者的执行流程,这是设计使然。

你可以做的是:

  • 抛出异常。它会冒泡,直到被某个地方捕获,然后迅速退出调用者。
  • 更改您的测试函数以进行有条件的返回,例如if (!assert(…)) return;

【讨论】:

    【解决方案3】:

    我认为不可能从函数中退出调用者。我建议一些解决方法:

    1.用你的Assert返回一个值,然后在调用者中执行return

    Assert = function ( expectedTrue, comment ) {
                if( ! expectedTrue ) {
                  Log.Error( comment );
                  return false;    
                }
                return true;
            }    
    Test123 ( ... ) {
            var assertResult = Assert( (inputField !== null ), "Checking that we found an input field");
            if (!assertResult)
                return;
            inputField.doSomething();
        }
    

    2.向您的Assert发送回调函数:

    Assert = function ( expectedTrue, comment, success) {
                if( ! expectedTrue ) {
                  Log.Error( comment );
                  return;    
                }
                success();
             } 
    assertSuccess = function () {
       inputField.doSomething();
    }
    Test123 ( ... ) {
        Assert( (inputField !== null ), "Checking that we found an input field", assertSuccess);
    }
    

    【讨论】:

    • 完全同意#1。关于#2,断言通常用于测试坏事,声明“不应该发生”。恕我直言,当断言失败时发送回调以“做”某事的用处不大,因为断言更像是“失去所有希望”类型错误:)
    • 为失败的断言发送回调,不会改变流程,doSomething() 方法将被命中。我也更喜欢 #1,但 #2 仍然是一个选项。