jQuery:Ajax调用成功后返回数据
我有这样的事情,这是一个简单的调用脚本,给我一个值,一个string..
function testAjax() { $.ajax({ url: "getvalue.php", success: function(data) { return data; } }); }
但如果我打电话这样
var output = testAjax(svar); // output will be undefined...
那么我怎样才能返还价值? 下面的代码似乎不工作…
function testAjax() { $.ajax({ url: "getvalue.php", success: function(data) { } }); return data; }
从函数返回数据的唯一方法是进行同步调用,而不是asynchronous调用,但是在等待响应时会冻结浏览器。
你可以传递一个处理结果的callback函数:
function testAjax(handleData) { $.ajax({ url:"getvalue.php", success:function(data) { handleData(data); } }); }
像这样调用它:
testAjax(function(output){ // here you use the output }); // Note: the call won't wait for the result, // so it will continue with the code here while waiting.
注意:这个答案是在2010年2月写的。
查看底部2015,2016和2017年的更新。
你不能从asynchronous函数中返回任何东西。 你可以回报的是一个承诺 。 我解释了在这些问题的答案中,jQuery中的承诺是如何工作的:
- 返回AJAX调用数据的JavaScript函数
- jQuery jqXHR – 取消链接调用,触发错误链
如果你能解释你为什么要返回数据,以后又想怎么处理,那么我可能会给你一个更具体的答案。
一般来说,而不是:
function testAjax() { $.ajax({ url: "getvalue.php", success: function(data) { return data; } }); }
你可以这样写你的testAjax函数:
function testAjax() { return $.ajax({ url: "getvalue.php" }); }
那么你可以得到这样的承诺:
var promise = testAjax();
你可以存储你的承诺,你可以传递它,你可以在函数调用中用它作为参数,你可以从函数中返回它,但是当你最终想要使用由AJAX调用返回的数据时,你必须像这样做:
promise.success(function (data) { alert(data); });
(有关简化语法,请参阅下面的更新。)
如果你的数据在这个时候是可用的,那么这个函数将被立即调用。 如果不是的话,只要数据可用,它就会被调用。
完成这一切的关键是,在调用$ .ajax之后,您的数据不会立即可用,因为它是asynchronous的。 承诺是一个很好的function抽象说:我不能返回你的数据,因为我还没有它,我不想阻止,让你等待,所以这是一个承诺,而不是,你将能够稍后使用它,或者把它交给其他人,并用它来完成。
看这个DEMO 。
更新(2015)
目前(截至2015年3月),jQuery Promise与Promises / A +规范不兼容,这意味着它们可能不能与其他Promises / A +一致的实现很好地协作。
然而,在即将到来的版本3.x中的jQuery Promise 将与Promises / A +规范兼容(感谢Benjamin Gruenbaum指出)。 目前(截至2015年5月),jQuery的稳定版本是1.x和2.x.
我上面解释的(2011年3月)是一种使用jQuery Deferred Objectsasynchronous执行某些事情的方法,即在同步代码中可以通过返回一个值来实现。
但同步函数调用可以做两件事情 – 它可以返回一个值(如果可以的话)或抛出一个exception(如果它不能返回一个值)。 Promises / A +以同样代码中的exception处理function强大的方式解决了这两种用例。 jQuery版本处理等价于返回一个值就好,但复杂的exception处理的等价物有些问题。
特别是,同步代码中exception处理的要点不仅仅是放弃一个好消息,而是试图解决问题并继续执行,或者可能重新抛出相同或不同的例外程序的其他部分处理。 在同步代码中,您有一个调用堆栈。 在asynchronous调用中,Promise / A +规范所要求的内部高级exception处理和Promise / A +规范所要求的高级exception处理确实可以帮助您编写能以有意义的方式处理错误和exception的代码,即使对于复杂的用例也是如此。
对于jQuery和其他实现之间的区别,以及如何将jQuery承诺转换为Promises / A +兼容,请参阅由Kris Kowal等人撰写的jQuery 。 在Q库wiki和Promise上,由Jake Archibald在HTML5 Rocks上获得JavaScript 。
如何回报真正的承诺
我上面的例子中的函数:
function testAjax() { return $.ajax({ url: "getvalue.php" }); }
返回一个jqXHR对象,它是一个jQuery Deferred Object 。
为了让它返回一个真正的承诺,你可以改变它 – 使用Q维基的方法 :
function testAjax() { return Q($.ajax({ url: "getvalue.php" })); }
或者使用HTML5 Rocks文章中的方法 :
function testAjax() { return Promise.resolve($.ajax({ url: "getvalue.php" })); }
这个Promise.resolve($.ajax(...))
也是在promise
模块文档中解释的 ,它应该和ES6 Promise.resolve()
。
要今天使用ES6 Promise,您可以使用Jake Archibald的es6-promise模块的polyfill polyfill()
。
要查看哪里可以使用ES6承诺没有polyfill,请参阅: 我可以使用:承诺 。
更多信息请参阅:
- http://bugs.jquery.com/ticket/14510
- https://github.com/jquery/jquery/issues/1722
- https://gist.github.com/domenic/3889970
- http://promises-aplus.github.io/promises-spec/
- http://www.html5rocks.com/en/tutorials/es6/promises/
未来的jQuery
未来版本的jQuery(从3.x开始 – 截至2015年5月的当前稳定版本是1.x和2.x)将与Promises / A +规范兼容(感谢Benjamin Gruenbaum在评论中指出)。 “我们已经决定的两个改变是Promise / A +兼容性,用于我们的延迟实现” ( jQuery 3.0和Web开发的未来 )。 欲了解更多信息,请参阅:由Dave Methvin和jQuery 3.0的jQuery 3.0: 下一代 :更多的互操作性,更less由Paul Krill的Internet Explorer 。
有趣的谈话
- Boom,Promises / A +由Domenic Denicola 出生 (JSConfUS 2013)
- 迈克尔·jackson(Michael Jackson)和多梅尼克·德尼科拉(Domenic Denicola)的callback地狱 (HTML5DevConf 2013)
- JavaScript的承诺大卫·李(2014年十二月)
更新(2016)
ECMA-262,第6版,第14.2节中有一个新的语法叫做箭头函数 ,可以用来进一步简化上面的例子。
使用jQuery API,而不是:
promise.success(function (data) { alert(data); });
你可以写:
promise.success(data => alert(data));
或使用Promises / A + API:
promise.then(data => alert(data));
请记住总是使用拒绝处理程序:
promise.then(data => alert(data), error => alert(error));
或与:
promise.then(data => alert(data)).catch(error => alert(error));
看到这个答案,看看为什么你应该总是使用拒绝处理程序的承诺:
- 我是否应该避免asynchronous处理Promise拒绝?
当然,在这个例子中,你可以只使用promise.then(alert)
因为你只是用与你的callback相同的参数调用alert
,但是箭头语法更一般,可以让你写下如下的东西:
promise.then(data => alert("x is " + data.x));
并不是所有的浏览器都支持这种语法,但是在某些情况下,您可以确定您的代码将运行在哪个浏览器上 – 例如,使用Electron,NW.js编写Chrome扩展程序 , Firefox附件或桌面应用程序AppJS(请参阅此答案的详细信息)。
有关箭头function的支持,请参阅:
- http://caniuse.com/#feat=arrow-functions
- http://kangax.github.io/compat-table/es6/#test-arrow_functions
更新(2017)
有一个更新的语法现在称为asynchronous函数与一个新的await
关键字,而不是这个代码:
functionReturningPromise() .then(data => console.log('Data:', data)) .catch(error => console.log('Error:', error));
让你写:
try { let data = await functionReturningPromise(); console.log('Data:', data); } catch (error) { console.log('Error:', error); }
您只能在使用async
关键字创build的函数中使用它。 有关更多信息,请参阅:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await
有关浏览器的支持,请参阅:
有关Node的支持,请参阅:
在你没有本地支持async
, await
你可以使用Babel:
或者使用稍微不同的语法,如co
或Bluebird协程中的基于生成器的方法:
更多信息
有关承诺的其他一些问题的更多细节:
- 承诺与承诺解决分离
- Q承诺延期
- 返回Promise结果而不是Promise
- 从诺言结果导出模块
- 诺言解决有什么问题?
- 从promise块返回函数中的值
- 我怎样才能返回承诺的状态?
- 我是否应该避免asynchronous处理Promise拒绝?
- JavaScript中的延迟/承诺概念是一个新概念,还是function性编程的一个传统部分?
- 我如何将这些function与承诺连接起来?
- Promise.all在JavaScript中:如何获得所有承诺的解决价值?
- 为什么Promise.all是不确定的
- 函数将从javascript post / get返回null
- 在promisifyAll创build的then-chain链中使用cancel()
- 为什么可以传递一个非函数参数给Promise.then()而不会导致错误?
- 实施承诺模式
- 承诺和performance
- 用承诺来解决两个URL的问题
- 即使在“结束”事件上指定返回后,http.request也不返回数据
- async.each在使用promise时不会迭代
- jQuery jqXHR – 取消链接调用,触发错误链
- 处理promisses和服务器响应的正确方法
- 在完成函数本身的所有操作之前,从函数调用中返回一个值?
- 解决API端点内的setTimeout问题
- asynchronous等待一个函数
- 返回AJAX调用数据的JavaScript函数
- 尝试/ catchasynchronous/等待块
- jQuery延迟不按顺序调用解决/完成callback
- 从Ajax返回数据会导致奇怪的对象
- 为什么有同步和asynchronous模块的规范?
您可以将asynchronous选项添加到false 并返回到ajax调用之外。
function testAjax() { var result=""; $.ajax({ url:"getvalue.php", async: false, success:function(data) { result = data; } }); return result; }
Idk如果你们解决了它,但我build议另一种方式来做到这一点,它的工作原理:)
ServiceUtil = ig.Class.extend({ base_url : 'someurl', sendRequest: function(request) { var url = this.base_url + request; var requestVar = new XMLHttpRequest(); dataGet = false; $.ajax({ url: url, async: false, type: "get", success: function(data){ ServiceUtil.objDataReturned = data; } }); return ServiceUtil.objDataReturned; } })
所以这里主要的想法是,通过添加asynchronous:false,然后让所有的东西等待,直到数据被检索。 然后你把它分配给这个类的一个静态variables,所有的东西都会神奇的工作:)
请参阅jquery文档示例: http : //api.jquery.com/jQuery.ajax/ (约2/3页)
您可能正在寻找以下代码:
$.ajax({ url: 'ajax/test.html', success: function(data) { $('.result').html(data); alert('Load was performed.'); } });
相同的页面…降低。