为自定义Javascript函数定义回调

时间:2015-06-09 18:44:52

标签: javascript function architecture callback

场景是我正在编写一些自定义的javascript方法,让我们假设。

function callMe(){
  //Do some stuff and return.
}

现在我想添加一些功能,我不确定它们是否会被视为回调但是会在某些时候被触发,因为 callMe() 是被执行。假设我希望只要有人调用 callMe() ,就需要执行 beforecallMe() / p>

function beforecallMe(){
// Do something and continue with callMe method

}

我想再次调用一个方法,一旦callMe执行了它的部分代码,就让方法 afterCallMe()

function afterCallMe(){
 //Triggered after callMe has executed
}

所以我有可能以Callbacks或任何其他方式做到这一点。

另外我想知道当某个特定函数要执行或执行时,它是否可以调用其他自定义函数作为回调,有点触发。

例如:有一种方法 sendmail() ,之后我希望有时打电话 sendReport() startaProgram() doSomething() 等等。有没有办法实现这个目标?

6 个答案:

答案 0 :(得分:1)

有很多方法可以解决这个问题。

这里有两个。

使用函数参数和其中包含函数的对象,然后使用回调。它们都是有效的,但如果你问我,回调就会简单一些。

//you can pass a parameter and
//use that in a switch statement
//to decide what to do
var funcs = {
    start: function(next) {

        switch (next) {
            case 1:
                this.startProgram();
                break;

            case 2:
                this.sendReport();
                break;

            case 3:
                this.doOtherThing();
                break;

            default:
                console.log('do nada');
                break;
        }
    },

    startProgram: function() {
        console.log("starting a program");
    },

    sendReport: function() {
        console.log("sending report");
    },

    doOtherThing: function() {
        console.log("Doing something else");
    }
};

funcs.start(1)
funcs.start()

//Or you can do it with callbacks
function doSomethingElse(callback) {
    console.log("doing something");
    callback();
}

doSomethingElse(function() {
    console.log("I'm a callback!");
});

答案 1 :(得分:0)

你可以这样做

function callMe()
{
    beforeCallMe();
    // CallMe code here
    afterCallMe();
}

beforeCallMe()将在callMe()方法的其余部分之前执行,然后afterCallMe()将被执行;

答案 2 :(得分:0)

您可以按如下方式定义功能:

function callMe(beforeCall, afterCall){
  if(typeof(beforeCall) === "function") beforeCall();

  // Your call me code goes here...

  if(typeof(afterCall) === "function") afterCall();
}

用法:

callMe(); // No callbacks
callMe(null, afterCall); // Will only call the afterCall
callMe(beforeCall, afterCall); // Will call both the beforeCall and afterCall

function beforeCall() {
  // before call function
}
function afterCall() {
  // after call function
}

或者您可以定义为匿名函数:

callMe(function () {
  // before call function
}, function () {
  // after call function
}); 

答案 3 :(得分:0)

有一百种方法可以做这样的事情。这是一个函数,它将接受3个函数,或者具有定义为参数的函数的对象。

<script>
    function write(txt) {
        document.getElementById("test").innerHTML = txt;
    }

    function append(txt) {
        var inner = document.getElementById("test").innerHTML;
        document.getElementById("test").innerHTML = inner + "<br>" + txt;
    }

    function callMe(callFunctionOrObject, callBefore, callAfter) {
        if (!callFunctionOrObject) return;

        if (typeof callFunctionOrObject === "object") {
            if (typeof callFunctionOrObject.callBefore === "function") {
                callFunctionOrObject.callBefore();
            }
            if (typeof callFunctionOrObject.call === "function") {
                callFunctionOrObject.call();
            }
            if (typeof callFunctionOrObject.callAfter === "function") {
                callFunctionOrObject.callAfter();
            }
        }
        else if (typeof callFunctionOrObject === "function") {
            if (typeof callBefore === "function") {
                callBefore();
            }
            callFunctionOrObject();
            if (typeof callAfter === "function") {
                callAfter();
            }
        }
    }

    //EXAMPLE USAGE
    append("First Test");
    callMe({
        "callBefore": function() { append("Before call 1"); },
        "call": function() { append("call 1"); },
        "callAfter": function() { append("After call 1"); }
    });

    append("Second Test");
    callMe(
        function() { append("call 2"); },
        function() { append("Before call 2"); },
        function() { append("After call 2"); }
    );
</script>

<div id="test"></div>

The Fiddle

答案 4 :(得分:0)

您可以动态执行此操作,设置前处理程序和/或后处理程序,以及为每个函数设置上下文参数。

以下代码有两个重要功能setupFunctionTriggers&amp; removeFunctionTriggers。其余的代码和html就是为了展示如何使用这些函数。

使用了一些关键技术:

  1. 命名函数可以像变量一样对待。它&#34;价值&#34;可以复制读取和分配(复制和替换)。
  2. 使用new Function()执行动态代码。
  3. new Function('return '+funcName+';')();将返回指定的函数本身。
  4. new Function('func', funcName+'=func;')(wrapperFunc);将使用新功能替换该功能。
  5. &#13;
    &#13;
    function setupFunctionTriggers(funcName, before, after, beforeArgs, afterArgs) {
      var func = new Function('return '+funcName+';')();
      var wrapperFunc = function() {
        if(before instanceof Function)
          before.apply(this, beforeArgs);
        
        var ret = func.apply(this, arguments);
    
        if(after instanceof Function)
          after.apply(this, afterArgs);
    
        return ret;
      };
    
      new Function('func', funcName+'=func;')(wrapperFunc);
      return func;
    }
    
    function removeFunctionTriggers(funcName, original) {
      new Function('func', funcName+'=func;')(original);
    }
    
    
    
    var log = '';
    
    function callMe(val) {
      log += 'Inside callMe(' + val + ')\n';
      return 'Called me!';
    }
    
    function before(val) {
      log += 'Before callMe, with val=' + val + '\n';
    }
    
    function after() {
      log += 'After callMe\n';
    }
    
    
    log += 'Call normal function\n';
    callMe(12);
    
    log += '\nSetup triggers...\n';
    var originalCallMe = setupFunctionTriggers('callMe', before , after, ['B4!']);
    
    var ret = callMe(34);
    log += 'callMe returned: ' + ret;
    
    log += '\n\nCall original function (triggers still attached)\n';
    originalCallMe(56);
    
    log += '\nReverting...\n';
    removeFunctionTriggers('callMe', originalCallMe);
    
    callMe(78);
    
    document.getElementById('log').innerHTML = '<pre>'+log+'</pre>';
    &#13;
    <span id="log"></span>
    &#13;
    &#13;
    &#13;

答案 5 :(得分:0)

我在Dan Davis在评论中提到的评论中找到了答案。

同样的小提琴是

http://jsfiddle.net/3h3f2y93/1/

和代码是:

Function.prototype.after=function(fn){
    var f=this;
    return function(){
        return fn.apply(this, arguments), f.apply(this, arguments);
    }
};

Function.prototype.before=function(fn){
    var f=this;
    return function(){
        return f.apply(this, arguments), fn.apply(this, arguments);
    }
};


function say1(){ alert(1); }
function say2(){ alert(2); }
function say3(){ alert(3); }

//say 2 before you say 1 and after you say 3:
 say2.before(say1).after(say3)();