【问题标题】:Pass parameters to Javascript callback functions将参数传递给 Javascript 回调函数
【发布时间】:2011-10-05 01:55:00
【问题描述】:

这就是我所拥有的:

function populateElement(arg1) {

    getData(arg1); 
}

function getData(query) {

    var url = "http://foo" + query + "&callback=processData";
    // do stuff 
}

function processData(results) {

    callbackForGetData(results); 
}

function callbackForGetData(result) { 

    // process data 
}

我想向函数 populateElement 传递另外两个参数,如下所示:

function populateElement(arg1, arg2, arg3) {

    getData(arg1);
}

并在 callbackForGetData 中提供 arg2、arg3

function callbackForGetData(result) {

    // process data
    // use arg2, arg3 here
}

我应该怎么做?

【问题讨论】:

  • 为什么不直接调用getData呢?
  • Appending multiple parameters/arguments to a jsonp callback function 的可能副本。我在回答这个问题时提供了一个解决方案的大纲。
  • @Adam:问题在于 callbackForGetData 被作为 JSONP 回调调用,因此 OP 无法控制它的调用方式。
  • 亩太短 - 首先,这不是转贴。我是 JS 和回调的新手,我真的不明白您所说的“无法控制它的调用方式”是什么意思。我可以更改 callbackForGetData

标签: javascript callback parameter-passing


【解决方案1】:

您可以将它们传递给回调并在arguments 数组中访问它们

function getData(result) {
  //result === arg1
  //arguments[0] === arg1
  //arguments[1] === arg2
  //arguments[2] === arg3
  //and so on
}

getData(arg1, arg2, arg3);

【讨论】:

  • 他的问题是如何在他的回调函数中得到arg1、arg2和arg3。
  • 我意识到这一点,但我假设他不想,或者不能改变回调,否则他可以向 getData 添加参数并使用它们
  • 这行不通。问题是回调是通过 JSONP 调用的。你需要do something like this
  • 你是怎么发现的?问题中没有说...:|
  • @James 我真的对回调感到困惑。我可以更改回调函数。你能举个例子吗?谢谢。
【解决方案2】:

将对象作为单个参数传递:

function populateElement(arg1, arg2, arg3) {

    var params = {"arg1":arg1,"arg2":arg2,"arg3",arg3};
    getData(params);
}

function getData(params) {

    var query = params.arg1;
    var url = "http://foo" + query + "&callback=processData";
    // do stuff 
}

【讨论】:

    【解决方案3】:

    您正在寻找关闭。

    function getData(query) {
        var url = "http://foo" + query + "&callback=processData";
        // do stuff
        //simulate the callback
        processData("some results");
    };
    
    function populateElement(arg1, arg2, arg3) {
        //Because we define processData here, we have a closure scope that
        // lets us see all the arguments to populateElement
        window.processData = function(results) {
            console.log("ProcessData called with results: " + results +
                ", arg2: " + arg2 + ", arg3: " + arg3);  
        };
        getData(arg1);
    }
    //Simulate the starting call
    populateElement(4, 5, 6);
    

    Here's a working jsfiddle.

    请注意,这只支持单 (1) 个待处理的 getData 调用。需要更精细的方案来支持多个并发挂起的 getData 调用。每个都需要一个唯一的回调闭包名称,可以像尾随数字序列号一样简单。

    【讨论】:

    • 我需要定义一个嵌套在populateElement 中的函数,这样我就可以通过闭包访问populateElement 参数。我明确分配给window,因为这样明确是最清晰和最不容易混淆的事情。否则,众所周知,JS 默认行为会令人困惑,因此最好避免歧义或意外/隐式行为。只是我的个人指导方针。
    【解决方案4】:

    要传递更多参数,您可以使用callapply

    function log(a, b, c) { console.log('A: ', a, ', b: ', b, ', c: ', c);}
    
    log.call(window, 'first', 'second', 'third');
    > A:  first , b:  second , c:  third
    
    log.apply(window, ['first', 'second', 'third'])
    > A:  first , b:  second , c:  third
    

    但正如 Peter 所建议的,您在此处进行了一些异步操作,您希望将其保存在闭包中,而不是传递额外的参数。

    有这样的东西,把你的数据保存在一个闭包中:

    function processData(results) {
      // transform data
      myModule.callbackForGetData(results); 
    }
    
    window.myModule = {
    
      populateElement: function(arg1, arg2, arg3) {
    
        this.data = arguments;
        this.getData(arg1); 
      },
    
      getData: function(query) {
    
        var script = document.createElement('script');
        script.src = 'http://jsfiddle.net/echo/jsonp/?query=' + query + '&callback=processData';
        document.getElementsByTagName('head')[0].appendChild(script)
      },
    
      callbackForGetData: function(result) { 
    
          // process data 
          console.log('Args: ', this.data, ', remote result: ', result);
      }
    }
    
    // test it
    myModule.populateElement(1, 2, 3)
    > Args:  [1, 2, 3] , remote result:  Object {query: "1"}
    

    【讨论】:

      猜你喜欢
      • 2011-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-05
      • 1970-01-01
      相关资源
      最近更新 更多