【问题标题】:how to terminate parent function execution in javascript?如何终止javascript中的父函数执行?
【发布时间】:2013-06-29 19:15:21
【问题描述】:

我需要重写函数的一些行为,在它调用其他函数之后。问题是这个父函数是一个库,我不想改变它,所以像做一些标志或这个函数的另一个改变这样的解决方案不是很好。我知道我在函数中有一个可以更改的调用者对象,所以也许我可以用它弄清楚。示例如下:

function parent()
{
  console.log("some need stuff");
  some.handler.function.from.config.that.i.can.change();
  console.log("need omit this right till the end");
}

function child()
{
  console.log("need to somehow stop evaluation of " + child.caller + " function");
}

作为一名 ruby​​ 程序员,我知道有 lambdas,您可以使用它从闭包的内部范围终止评估。但我不确定如何从 javascript 执行此操作。

【问题讨论】:

  • 我已经为您的问题发布了一个可能的解决方案 - 我认为它与您的要求一样好。但是,按照我的建议做通常不是最好的方法。我怀疑the XY problem。如果您在此处遇到更具体的问题,请考虑针对实际问题提出新问题。强烈建议不要为此使用异常。
  • 你总是可以抛出,但尽可能使用异步技术。

标签: javascript closures evaluation


【解决方案1】:

你不能直接这样做。 (而且.caller 已经过时了)

但是你可以使用一个肮脏的把戏:

try{
    parentFunction();//calls child
}catch(e){
   //done
}

function child(){
    doWhatever();
    throw new Error("this will hopefully propagate");
}

Fiddle

这只有在父级调用子级时没有自己捕获异常的情况下才有效。

此外,使用异常进行流控制通常是个坏主意。将此作为最后的手段。

【讨论】:

  • 本杰明,我已经尝试在我自己的答案中添加一些额外的价值(目前如下)。会对您的想法感兴趣。
【解决方案2】:

在调用库之前调用您控制的新函数,并将对您无法修改的库的调用包装在 try/catch 块中。

例如:

function meta-parent()
{
  try {
    parent();
  }
  catch (e){
      // don't really be empty!
  }
}

function parent()
{
  console.log("some need stuff");
  some.handler.function.from.config.that.i.can.change();
  // Nothing below here will run because of your child's exception
  console.log("need omit this right till the end");  
}

function child()
{
  console.log("need to somehow stop evaluation of " + child.caller + " function");
  throw new Error(); //breakout!
}

笔记灵感:Breaking a parent function from within a child function (PHP Preferrably)

【讨论】:

  • 这与我 8 分钟前的解决方案有何不同?
  • @Benjamin。无显着差异;您只是输入得更快,但是在我开始之后,所以我不知道单击时已经发布了答案。 (您可能会说我是新来的……我应该删除无关的答案吗?)
  • 詹姆斯,您的回答非常好,您对添加它的原因的解释似乎是合理的。我不是要你删除它(其他人也不是)。如果您认为它对我有用 - 非常欢迎您将其保留在这里。
【解决方案3】:

正如 Benjamin Gruenbaum 所指出的,使用异常来进行流控制应该被视为最后的手段,但是 Promises/A 提案(在某些实现中)是否不能以这种方式利用异常合法化?

我确实认为从子函数抛出的(否则未被捕获的)错误可能不是 Promises/A 作者所想的(即我们仍然可以说是在谈论“肮脏的把戏”),但是Promises/A 提案也没有明确排除这种错误传播。

Q 库是解决这个问题的理想选择,允许这样的事情:

Q.fcall(parentFunction).then(function (value) {
    alert(value);
}, function (error) {
    alert(error);
});

fiddle

请注意,为方便起见,我还在小提琴中使用 jQuery,但只是为按钮提供功能。

【讨论】:

  • 拥有协程(使用yield)关键字将允许您使用常规的try/catch(参见Q.async!)。虽然 resolve/reject 与 try/catch 类似(并且通常表示相同的东西,例如,ajax 失败似乎适合“catch”子句)但它们在概念上并不完全相同(ps 我什至 implemented asynchronous catch for node for fun :) 与 promise 一起玩-like 语法。不过,您提出的观点是有效且有趣的。
  • 无论如何,我认为这个答案本身就是programmers.stackexchange.com上的一个有趣问题。就目前而言,它不会尝试回答 op 的问题。我认为一个关于程序员的独立问题既是它所属的地方,也应该引起其他开发者的注意。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-20
  • 2017-09-01
  • 1970-01-01
相关资源
最近更新 更多