jQuery将更多的参数传入callback

有没有办法将更多的数据传递到jQuery中的callback函数?

我有两个函数,我想callback到$.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) { } 

我希望能够将我自己的parameter passing给callback,以及从AJAX调用返回的结果。

解决的办法是通过闭包绑定variables。


作为一个更基本的例子,下面是一个接收和调用callback函数的示例函数,以及一个示例callback函数:

 function callbackReceiver(callback) { callback("Hello World"); } function callback(value1, value2) { console.log(value1, value2); } 

这将调用callback并提供一个参数。 现在你想提供一个额外的参数,所以你把闭包中的callback。

 callbackReceiver(callback); // "Hello World", undefined callbackReceiver(function(value) { callback(value, "Foo Bar"); // "Hello World", "Foo Bar" }); 

或者,更简单地使用ES6箭头函数 :

 callbackReceiver(value => callback(value, "Foo Bar")); // "Hello World", "Foo Bar" 

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

 function callBack(data, textStatus, jqXHR) {}; 

所以我觉得解决方法如下:

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

发生什么事?

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

因为extraStuff作为parameter passing给doSomething它在doSomething函数的作用域内。

当在doSomething的返回的匿名内部函数中引用extraStuff ,它被封闭到外部函数的extraStuff参数。 即使doSomething已经返回,情况也是如此。

我没有testing过上面的代码,但是我在过去的24小时里写了非常类似的代码,并且按照我的描述工作。

您当然可以传递多个variables,而不是一个“extraStuff”对象,具体取决于您的个人偏好/编码标准。

当使用doSomething(data, myDiv) ,实际上调用函数并且不要引用它。

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

如果你想保持它的方式,你可以用匿名函数包装其呼叫。

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

在匿名函数代码中,可以使用封闭范围中定义的variables。 这是Javascript范围的工作方式。

这实际上比每个人的声音都更容易,特别是如果使用$.ajax({})基本语法与其中一个辅助函数。

只要像设置你的ajax请求那样通过key: value对就可以了(因为$(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> 

原因之一是设置var,这个var是全局的,因此是可覆盖的。如果你有两件事情可以触发ajax调用,理论上你可以比ajax调用响应更快地触发它们,你会有第二次通话的价值。 使用上面的这种方法,这不会发生(而且使用起来也非常简单)。

在当今世界有另一个更清洁的答案,并从另一个堆栈溢出答案:

 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. ... } 

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

您也可以尝试如下所示:

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

您可以使用JavaScript的closures:

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

当你可以做:

 $.post("someurl.php",data,wrapper(var1, var2, etc...),"html"); 

我在上一篇文章中犯了一个错误。 这是如何在callback函数中传递额外参数的工作示例:

 function custom_func(p1,p2) { $.post(AJAX_FILE_PATH,{op:'dosomething',p1:p1}, function(data){ return function(){ alert(data); alert(p2); }(data,p2) } ); return false; } 

让我们去简单! 🙂

 $.ajax({ url: myUrl, context: $this, // $this == Current $element success: function(data) { $.proxy(publicMethods.update, this)(data); // this == Current $element } }); 

使用.ajax() jQuery API发送asynchronous请求的更一般的解决scheme,以及将更多parameter passing给callback函数的闭包:

 function sendRequest(method, url, content, callback) { // additional data for the callback var request = { method: method, url: url }; $.ajax({ type: method, url: url, data: content }).done(function(data, status, xhr) { if (callback) callback(xhr.status, data, request); }).fail(function(xhr, status) { if (callback) callback(xhr.status, xhr.response, request); }); }; 

对于我和其他刚接触Javascript的新手来说,
我认为Closeure Solution有点太混乱了。

虽然我发现,你可以easilly通过尽可能多的参数,你想每个Ajaxcallback使用jQuery。

这是两个更简单的解决scheme

第一个, @zeroasterisk上面提到的例子:

 var $items = $('.some_class'); $.each($items, function(key, item){ var url = 'http://request_with_params' + $(item).html(); $.ajax({ selfDom : $(item), selfData : 'here is my self defined data', url : url, dataType : 'json', success : function(data, code, jqXHR){ // in $.ajax callbacks, // [this] keyword references to the options you gived to $.ajax // if you had not specified the context of $.ajax callbacks. // see http://api.jquery.com/jquery.ajax/#jQuery-ajax-settings context var $item = this.selfDom; var selfdata = this.selfData; $item.html( selfdata ); ... } }); }); 

其次,将自定义数据join到整个Ajax请求响应生命周期中的XHR object中。

 var $items = $('.some_class'); $.each($items, function(key, item){ var url = 'http://request_with_params' + $(item).html(); $.ajax({ url : url, dataType : 'json', beforeSend : function(XHR) { // 为了便于callback,把当前的 jquery对象集存入本次 XHR XHR.selfDom = $(item); XHR.selfData = 'here is my self defined data'; }, success : function(data, code, jqXHR){ // jqXHR is a superset of the browser's native XHR object var $item = jqXHR.selfDom; var selfdata = jqXHR.selfData; $item.html( selfdata ); ... } }); }); 

正如你可以看到这两个解决scheme有一个缺点:你需要写更多的代码,而不是只写:

 $.get/post (url, data, successHandler); 

阅读更多关于$ .ajax的信息: http : //api.jquery.com/jquery.ajax/

 $(document).on('click','[action=register]',function(){ registerSocket(registerJSON(),registerDone,second($(this))); }); function registerSocket(dataFn,doneFn,second){ $.ajax({ type:'POST', url: "http://localhost:8080/store/public/register", contentType: "application/json; charset=utf-8", dataType: "json", data:dataFn }).done ([doneFn,second]) .fail(function(err){ console.log("AJAX failed: " + JSON.stringify(err, null, 2)); }); } function registerDone(data){ console.log(JSON.stringify(data)); } function second(element){ console.log(element); } 

次要方法:

 function socketWithParam(url,dataFn,doneFn,param){ $.ajax({ type:'POST', url:url, contentType: "application/json; charset=utf-8", headers: { 'Authorization': 'Bearer '+localStorage.getItem('jwt')}, data:dataFn }).done(function(data){ doneFn(data,param); }) .fail(function(err,status,xhr){ console.log("AJAX failed: " + JSON.stringify(err, null, 2)); }); } $(document).on('click','[order-btn]',function(){ socketWithParam(url,fakeDataFn(),orderDetailDone,secondParam); }); function orderDetailDone(data,param){ -- to do something -- } 

作为b01的答案的附录, $.proxy的第二个参数经常被用来保存this引用。 传递给$.proxy附加参数部分应用于该函数,预填充数据。 请注意, $.post传递给callback函数的任何参数将在最后应用,因此doSomething应该在其参数列表的末尾添加:

 function clicked() { var myDiv = $("#my-div"); var callback = $.proxy(doSomething, this, myDiv); $.post("someurl.php",someData,callback,"json"); } function doSomething(curDiv, curData) { //"this" still refers to the same "this" as clicked() var serverResponse = curData; } 

这种方法还允许将多个参数绑定到callback:

 function clicked() { var myDiv = $("#my-div"); var mySpan = $("#my-span"); var isActive = true; var callback = $.proxy(doSomething, this, myDiv, mySpan, isActive); $.post("someurl.php",someData,callback,"json"); } function doSomething(curDiv, curSpan, curIsActive, curData) { //"this" still refers to the same "this" as clicked() var serverResponse = curData; } 

如果还有人来这里,这是我的意思:

 $('.selector').click(myCallbackFunction.bind({var1: 'hello', var2: 'world'})); function myCallbackFunction(event) { var passedArg1 = this.var1, passedArg2 = this.var2 } 

绑定到callback函数后会发生什么,在这个函数中可以使用。

这个想法来自于React如何使用bindfunction。

其实,你的代码不工作,因为当你写:

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

您将函数调用作为第三个参数而不是函数引用