简体   繁体   English

定义自定义Javascript函数的回调

[英]Defining Callbacks for custom Javascript Functions

The scenario is i am writing some custom javascript method lets say suppose. 场景是我在写一些自定义的javascript方法。

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

Now i want to add some functions, i am not sure if they will be treated as callback but which will be triggered at some point as the callMe() is being executed. 现在,我想添加一些函数,我不确定它们是否会被当作回调,但在执行callMe()时会在某些时候触发。 Lets say i want the beforecallMe() needs to be executed as soon as somebody calls callMe() methof 可以说,我想beforecallMe()需要为有人打电话呼我()methof被尽快执行

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

} }

Again i want to call a method as soon as the callMe has executed its part of code, lets say method afterCallMe() . 再一次,我想在callMe执行了代码的一部分后立即调用一个方法,让我们说方法afterCallMe()

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

So is there any possible way i can do this in Callbacks or any other way. 因此,有没有可能我可以在回调或任何其他方式中做到这一点。

Also i want to know if its possible call other custom functions as callbacks when a particular function is going to execute or has executed, somewhat a trigger. 我也想知道当一个特定的函数要执行或已经执行时,是否有可能调用其他自定义函数作为回调,有点触发。

For eg : There is a method sendmail() after which i wish to call sometimes sendReport() or startaProgram() or doSomething() and so on. 例如:有一个方法sendmail(),此后我希望有时调用sendReport()startaProgram()doSomething()等。 Is there any way to do achieve this ? 有什么办法可以做到这一点?

There's plenty of ways to handle this. 有很多方法可以解决这个问题。

Here's two. 这是两个

One using a function parameter and an object with functions inside it then using callbacks. 一种使用函数参数,而一个对象内部带有函数,然后使用回调。 They're both valid, but callbacks are a bit simpler, if you ask me. 它们都有效,但是如果您问我,回调函数会更简单。

//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!");
});

You could just do this 你可以这样做

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

beforeCallMe() will a execute before the rest of the callMe() method and then afterCallMe() will be executed; beforeCallMe()将在其余callMe()方法之前执行,然后将执行afterCallMe()

You can define the function as follows: 您可以如下定义函数:

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

  // Your call me code goes here...

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

Usage: 用法:

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
}

or you can define as anonymous functions: 或者您可以定义为匿名函数:

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

There are a hundred ways to do something like this. 有一百种方法可以做这样的事情。 Here is a function that will accept either 3 functions, or an object with the functions defined as parameters. 这是一个将接受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 小提琴

You can do this dynamically, setup a before and/or after handler, as well as setup context arguments for each function. 您可以动态地执行此操作,设置before和/或after处理程序,以及为每个函数设置上下文参数。

The code below has 2 important functions setupFunctionTriggers & removeFunctionTriggers . 下面的代码具有2个重要功能setupFunctionTriggersremoveFunctionTriggers The rest of the code and html are just there to show how to use these functions. 其余的代码和html都在这里展示了如何使用这些功能。

A few key techniques used: 使用的一些关键技术:

  1. A Named function can be treated like a variable. 命名函数可以像变量一样对待。 It's "value" can be copied read and assigned to (copied and replaced). 可以将其“值”复制并读取并分配给(复制并替换)。
  2. Use new Function() to execute dynamic code. 使用new Function()执行动态代码。
  3. new Function('return '+funcName+';')(); Will return the named function itself. 将返回命名函数本身。
  4. new Function('func', funcName+'=func;')(wrapperFunc); Will replace the function with a new function. 将用新功能替换该功能。

 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>'; 
 <span id="log"></span> 

I have found answer in the comments as mentioned by Dan Davis in comments. 我在Dan Davis在评论中提到的评论中找到了答案。

And the fiddle for the same is 同样的小提琴是

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

and Code is : 和代码是:

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)();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM