[removed] Passing parameters to a callback function

后端 未结 13 2118
隐瞒了意图╮
隐瞒了意图╮ 2020-11-22 15:48

I\'m trying to pass some parameter to a function used as callback, how can I do that?

function tryMe (param1, param2) {
    alert (param1 + \" and \" + param         


        
相关标签:
13条回答
  • 2020-11-22 16:10

    A new version for the scenario where the callback will be called by some other function, not your own code, and you want to add additional parameters.

    For example, let's pretend that you have a lot of nested calls with success and error callbacks. I will use angular promises for this example but any javascript code with callbacks would be the same for the purpose.

    someObject.doSomething(param1, function(result1) {
      console.log("Got result from doSomething: " + result1);
      result.doSomethingElse(param2, function(result2) {
        console.log("Got result from doSomethingElse: " + result2);
      }, function(error2) {
        console.log("Got error from doSomethingElse: " + error2);
      });
    }, function(error1) {
      console.log("Got error from doSomething: " + error1);
    });
    

    Now you may want to unclutter your code by defining a function to log errors, keeping the origin of the error for debugging purposes. This is how you would proceed to refactor your code:

    someObject.doSomething(param1, function (result1) {
      console.log("Got result from doSomething: " + result1);
      result.doSomethingElse(param2, function (result2) {
        console.log("Got result from doSomethingElse: " + result2);
      }, handleError.bind(null, "doSomethingElse"));
    }, handleError.bind(null, "doSomething"));
    
    /*
     * Log errors, capturing the error of a callback and prepending an id
     */
    var handleError = function (id, error) {
      var id = id || "";
      console.log("Got error from " + id + ": " + error);
    };
    

    The calling function will still add the error parameter after your callback function parameters.

    0 讨论(0)
  • 2020-11-22 16:11

    If you want something slightly more general, you can use the arguments variable like so:

    function tryMe (param1, param2) {
        alert(param1 + " and " + param2);
    }
    
    function callbackTester (callback) {
        callback (arguments[1], arguments[2]);
    }
    
    callbackTester (tryMe, "hello", "goodbye");
    

    But otherwise, your example works fine (arguments[0] can be used in place of callback in the tester)

    0 讨论(0)
  • 2020-11-22 16:11

    Wrap the 'child' function(s) being passed as/with arguments within function wrappers to prevent them being evaluated when the 'parent' function is called.

    function outcome(){
        return false;
    }
    
    function process(callbackSuccess, callbackFailure){
        if ( outcome() )
            callbackSuccess();
        else
            callbackFailure();
    }
    
    process(function(){alert("OKAY");},function(){alert("OOPS");})
    
    0 讨论(0)
  • 2020-11-22 16:11

    Code from a question with any number of parameters and a callback context:

    function SomeFunction(name) {
        this.name = name;
    }
    function tryMe(param1, param2) {
        console.log(this.name + ":  " + param1 + " and " + param2);
    }
    function tryMeMore(param1, param2, param3) {
        console.log(this.name + ": " + param1 + " and " + param2 + " and even " + param3);
    }
    function callbackTester(callback, callbackContext) {
        callback.apply(callbackContext, Array.prototype.splice.call(arguments, 2));
    }
    callbackTester(tryMe, new SomeFunction("context1"), "hello", "goodbye");
    callbackTester(tryMeMore, new SomeFunction("context2"), "hello", "goodbye", "hasta la vista");
    
    // context1: hello and goodbye
    // context2: hello and goodbye and even hasta la vista
    
    0 讨论(0)
  • 2020-11-22 16:12

    Your question is unclear. If you're asking how you can do this in a simpler way, you should take a look at the ECMAScript 5th edition method .bind(), which is a member of Function.prototype. Using it, you can do something like this:

    function tryMe (param1, param2) {
        alert (param1 + " and " + param2);
    }
    
    function callbackTester (callback) {
        callback();
    }
    
    callbackTester(tryMe.bind(null, "hello", "goodbye"));
    

    You can also use the following code, which adds the method if it isn't available in the current browser:

    // From Prototype.js
    if (!Function.prototype.bind) { // check if native implementation available
      Function.prototype.bind = function(){ 
        var fn = this, args = Array.prototype.slice.call(arguments),
            object = args.shift(); 
        return function(){ 
          return fn.apply(object, 
            args.concat(Array.prototype.slice.call(arguments))); 
        }; 
      };
    }
    

    Example

    bind() - PrototypeJS Documentation

    0 讨论(0)
  • 2020-11-22 16:15

    Let me give you a very plain Node.js style example of using a callback:

    /**
     * Function expects these arguments: 
     * 2 numbers and a callback function(err, result)
     */
    var myTest = function(arg1, arg2, callback) {
      if (typeof arg1 !== "number") {
        return callback('Arg 1 is not a number!', null); // Args: 1)Error, 2)No result
      }
      if (typeof arg2 !== "number") {
        return callback('Arg 2 is not a number!', null); // Args: 1)Error, 2)No result
      }
      if (arg1 === arg2) {
        // Do somethign complex here..
        callback(null, 'Actions ended, arg1 was equal to arg2'); // Args: 1)No error, 2)Result
      } else if (arg1 > arg2) {
        // Do somethign complex here..
        callback(null, 'Actions ended, arg1 was > from arg2'); // Args: 1)No error, 2)Result
      } else {
        // Do somethign else complex here..
        callback(null, 'Actions ended, arg1 was < from arg2'); // Args: 1)No error, 2)Result
      }
    };
    
    
    /**
     * Call it this way: 
     * Third argument is an anonymous function with 2 args for error and result
     */
    myTest(3, 6, function(err, result) {
      var resultElement = document.getElementById("my_result");
      if (err) {
        resultElement.innerHTML = 'Error! ' + err;
        resultElement.style.color = "red";
        //throw err; // if you want
      } else {
        resultElement.innerHTML = 'Result: ' + result;
        resultElement.style.color = "green";
      }
    });
    

    and the HTML that will render the result:

    <div id="my_result">
      Result will come here!
    </div>
    

    You can play with it here: https://jsfiddle.net/q8gnvcts/ - for example try to pass string instead of number: myTest('some string', 6, function(err, result).. and see the result.

    I hope this example helps because it represents the very basic idea of callback functions.

    0 讨论(0)
提交回复
热议问题