1

也许你们中的一些人了解 AOP,在某些语言中使用 AOP 可以让您能够在方法执行之后、之前或期间注入代码等。

我想要的是在 Javascript 中应用相同的内容,我目前正在开发一个具有 300 多个 ajax 调用的大型应用程序,每次我需要对它们的 catch 语句进行一些更改时,我都必须通过一个非常乏味的。

我想做的是:

functionName.before("try {")

functionName.after("} catch(ex){
//dostuff
}")

是否可以?我知道有诸如 .call 之类的东西,或者每个函数中的 arguments 对象……它们看起来很像元函数 (AOP) 功能。

4

4 回答 4

3

不是beforeand after,而是 awrap会起作用:

Function.prototype.wrapTry = function(handle) {
    var fn = this;
    return function() {
        try {
            return fn.apply(this, arguments);
        } catch(e) {
            return handle(e);
        }
    };
};

然后像这样使用它

var safeFunction = functionName.wrapTry(doStuff);
于 2014-07-23T13:45:38.703 回答
0

在 JavaScript 中,函数是一流的对象。这意味着您可以操纵或重新声明它们。

假设有一个“foo”函数:

var originalFoo = foo;
foo = function()
{
    // "before" code.

    // Call the original function.
    originalFoo.apply(this, arguments);

    // "after" code.
};

之后,对 foo() 的任何调用都将调用新函数:即使带有参数。

于 2014-07-23T14:01:13.967 回答
0

老问题,但你可以看看这个https://github.com/k1r0s/kaop-ts/blob/master/docs/api.md#available-join-points

import { onException } from "kaop-ts"
import handlingException from "./somewhere"

class Something {

  @onException(handlingException)
  method() {
    // stuff that may throw an error
  }
}
于 2018-01-29T09:25:56.107 回答
0

我还将给出一个较晚的答案,以便对这种特殊情况有所了解,这种情况时不时地以JavaScript 和 AOP的形式出现。

首先,像 OP 提出的这种情况总是要求修改已经存在的功能,从而针对封闭的代码,这些代码有时甚至不属于认为自己因修改此类代码的控制流而受到挑战的一方。

那么,为什么不只是这样命名... JavaScript 方法修改JavaScript 方法修饰符

其次,由于已经骑着术语,改变 JavaScript 中的封闭功能与面向切面编程无关,除非声称是AO的实现至少为AspectAdvicePointcut提供抽象和代码重用级别。

最后,对于 OP 将要实现的目标以及公认的答案,确实存在一大堆before, after around/wrap解决方案,不幸的是几乎总是提到AO(P),并且在太多情况下没有考虑到上下文target方法修改至关重要。

我提供的示例使用afterThrowing. 由于bindJavaScript 已经具有标准化 的. Function.prototype_ _ _beforeafteraroundafterThrowingafterFinally

// OP's example pseudo code
//
// functionName.before("try {")
//
// functionName.after("} catch(ex){
//   dostuff
// }")

function doStuffAfterThrowing(exception, originalArguments) {
  "use strict";
  var context = this;

  console.log('context : ', context);
  console.log('String(exception) : ', String(exception));
  console.log('originalArguments : ', originalArguments);

  return "safely handled exception";
}


function doFail() {
  throw (new ReferenceError);
}
function oneOutOfManyAjaxCallbacks(payload) {
  doFail();
}
var jsonData = {
  "foo": "foo",
  "bar": "bar"
};


var someModifiedAjaxCallback = oneOutOfManyAjaxCallbacks.afterThrowing(doStuffAfterThrowing, { x: 'y' });

// does fail controlled/handled.
console.log('someModifiedAjaxCallback(jsonData) : ', someModifiedAjaxCallback(jsonData));

// does fail "Uncaught".
console.log('oneOutOfManyAjaxCallbacks(jsonData) : ', oneOutOfManyAjaxCallbacks(jsonData));
.as-console-wrapper { min-height: 100%!important; top: 0; }
<script>
  (function (Function) {
    var
      isFunction = function (type) {
        return (
             (typeof type == "function")
          && (typeof type.call == "function")
          && (typeof type.apply == "function")
        );
      },
      getSanitizedTarget = function (target) {
        return ((target != null) && target) || null;
      }
    ;
    Function.prototype.afterThrowing = function (handler, target) { // afterThrowing
      target  = getSanitizedTarget(target);
      var proceed = this ;

      return (isFunction(handler) && isFunction(proceed) && function () {
        var ret, args = arguments;
        try {
          ret = proceed.apply(target, args);
        } catch (exc) {
          ret = handler.call(target, exc, args);
        //throw exc;
        }
        return ret;

      }) || proceed;
    };
  }(Function));
</script>

走到这一步,人们也可以考虑阅读......

于 2018-01-29T11:02:04.947 回答