jQuery将更多参数传递给回调

atp*_*atp 252 javascript jquery arguments function callback

有没有办法将更多数据传递给jQuery中的回调函数?

我有两个函数,我希望回调$.post,例如,传递AJAX调用的结果数据,以及一些自定义参数

function clicked() {
    var myDiv = $("#my-div");
    // ERROR: Says data not defined
    $.post("someurl.php",someData,doSomething(data, myDiv),"json"); 
    // ERROR: Would pass in myDiv as curData (wrong)
    $.post("someurl.php",someData,doSomething(data, myDiv),"json"); 
}

function doSomething(curData, curDiv) {

}
Run Code Online (Sandbox Code Playgroud)

我希望能够将自己的参数传递给回调,以及从AJAX调用返回的结果.

bra*_*use 337

解决方案是通过闭包绑定变量.


作为一个更基本的例子,这里是一个接收和调用回调函数的示例函数,以及一个示例回调函数:

function callbackReceiver(callback) {
    callback("Hello World");
}

function callback(value1, value2) {
    console.log(value1, value2);
}
Run Code Online (Sandbox Code Playgroud)

这会调用回调并提供单个参数.现在你想提供一个额外的参数,所以你将回调包装在闭包中.

callbackReceiver(callback);     // "Hello World", undefined
callbackReceiver(function(value) {
    callback(value, "Foo Bar"); // "Hello World", "Foo Bar"
});
Run Code Online (Sandbox Code Playgroud)

或者,更简单地使用ES6箭头功能:

callbackReceiver(value => callback(value, "Foo Bar")); // "Hello World", "Foo Bar"
Run Code Online (Sandbox Code Playgroud)

至于你的具体例子,我没有.post在jQuery中使用该函数,但是对文档的快速扫描表明回调应该是具有以下签名的函数指针:

function callBack(data, textStatus, jqXHR) {};
Run Code Online (Sandbox Code Playgroud)

因此我认为解决方案如下:

var doSomething = function(extraStuff) {
    return function(data, textStatus, jqXHR) {
        // do something with extraStuff
    };
};

var clicked = function() {
    var extraStuff = {
        myParam1: 'foo',
        myParam2: 'bar'
    }; // an object / whatever extra params you wish to pass.

    $.post("someurl.php", someData, doSomething(extraStuff), "json");
};
Run Code Online (Sandbox Code Playgroud)

怎么了?

在最后一行中,doSomething(extraStuff)调用和该调用的结果是一个函数指针.

因为extraStuff它作为参数传递给doSomething它在doSomething函数的范围内.

extraStuff在返回的匿名内部函数中引用doSomething它时,它被闭包到外部函数的extraStuff参数.doSomething返回后即使如此也是如此.

我没有对上面的内容进行测试,但是我在过去的24小时内编写了非常相似的代码,它的工作原理正如我所描述的那样.

您当然可以传递多个变量而不是单个'extraStuff'对象,具体取决于您的个人偏好/编码标准.

  • 这不是真的.不同的范围规则适用于这两个函数声明.根据JS运行时(读取浏览器),行为有很大不同.还尝试比较Firebug中stacktrace/breakpoint中显示的函数名称. (6认同)
  • *此答案的第4版正在[讨论meta](http://meta.stackoverflow.com/q/338481/237186​​1)* (4认同)
  • 由于示例的特殊性,对于尝试将其应用于更一般问题的用户来说,这可能有点难以理解。我添加了一个简化的示例,使其更容易理解,以及一个箭头函数示例,以防止此问题作为新发布的建议副本的副本而关闭。如果您觉得我的编辑与您的答案的初衷背道而驰,或者在任何其他方面不合适,请随时将其回滚。 (2认同)

Vin*_*ert 81

使用时doSomething(data, myDiv),实际上是调用函数而不是引用它.

您可以doStomething直接传递函数,但必须确保它具有正确的签名.

如果你想按照它的方式保持doSomething,你可以将它的调用包装在一个匿名函数中.

function clicked() {
    var myDiv = $("#my-div");
    $.post("someurl.php",someData, function(data){ 
      doSomething(data, myDiv)
    },"json"); 
}

function doSomething(curData, curDiv) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

在匿名函数代码中,您可以使用封闭范围中定义的变量.这是Javascript作用域的工作方式.

  • 为了清楚起见,这是IMO的最佳解决方案.在`doSomething`函数中没有额外的`return function(...){...}`函数.我在这里找到了另一个相同概念的明显例子:http://theelitist.net/passing-additional-arguments-to-a-callback-function-in-javascript (9认同)
  • 我觉得这个有问题.如果您的额外数据(在这种情况下为myDiv)在回调触发之前发生变化,您将获得新值而不是旧值!在我的情况下,我在数组中的项目上触发了ajax调用,并且在执行第一个success()调用时,它认为它在第一个项目的最后一个项目上成功了!布拉德豪斯的回答对我有用. (4认同)

zer*_*isk 51

它实际上比每个人都更容易听起来更容易......特别是如果你使用$.ajax({})基本语法与其中一个辅助函数.

key: value当您设置ajax请求时,就像在任何对象上一样传入对... (因为$(this)尚未更改上下文,它仍然是上面绑定调用的触发器)

<script type="text/javascript">
$(".qty input").bind("keypress change", function() {
    $.ajax({
        url: "/order_items/change/"+$(this).attr("data-order-item-id")+"/qty:"+$(this).val()+"/returnas.json",
        type: "POST",
        dataType: "json",
        qty_input: $(this),
        anything_else_i_want_to_pass_in: "foo",
        success: function(json_data, textStatus, jqXHR) {
            /* here is the input, which triggered this AJAX request */
            console.log(this.qty_input);
            /* here is any other parameter you set when initializing the ajax method */
            console.log(this.anything_else_i_want_to_pass_in);
        }
    });
});
</script>
Run Code Online (Sandbox Code Playgroud)

这比设置var更好的原因之一是var是全局的,因此是可覆盖的...如果你有2个可以触发ajax调用的东西,理论上你可以比ajax调用响应更快地触发它们,你有第二个调用传递给第一个调用的值.使用上面的方法,这不会发生(并且使用它也很简单).

  • @LorenzoPolidori我不同意,我发现附加参数方法更具可读性. (5认同)
  • 这正是我想要的.我不知道你何时将dataType指定为json,它会自动为你解析响应.那很好(: (3认同)
  • 这绝对是辉煌的.为什么我以前从未见过这个.我不需要`封闭'我只需要它工作,这绝对是王牌,干净,简单和非全局. (2认同)

b01*_*b01 20

在今天的世界中,还有另一个更清晰的答案,并取自另一个Stack Overflow答案:

function clicked()
{
    var myDiv = $( "#my-div" );

    $.post( "someurl.php", {"someData": someData}, $.proxy(doSomething, myDiv), "json" );
}

function doSomething( data )
{
    // this will be equal to myDiv now. Thanks to jQuery.proxy().
    var $myDiv = this;

    // doing stuff.
    ...
}
Run Code Online (Sandbox Code Playgroud)

这是原始问题和答案: jQuery如何?将附加参数传递给$ .ajax调用的成功回调?


Roh*_*ida 8

您还可以尝试以下内容:

function clicked() {

    var myDiv = $("#my-div");

    $.post("someurl.php",someData,function(data){
        doSomething(data, myDiv);
    },"json"); 
}

function doSomething(curData, curDiv) {

}
Run Code Online (Sandbox Code Playgroud)


Art*_*ger 5

您可以使用JavaScript的闭包:

function wrapper( var1, var2,....) // put here your variables
{
  return function( data, status)
  {
     //Handle here results of call
  }
};
Run Code Online (Sandbox Code Playgroud)

当你能做到:

$.post("someurl.php",data,wrapper(var1, var2, etc...),"html");
Run Code Online (Sandbox Code Playgroud)