jQuery:在Ajax调用成功后返回数据
这个问题在这里已经有了答案:
从函数中返回数据的唯一方法是进行同步调用而不是异步调用,但这会在浏览器等待响应时冻结浏览器。
你可以传递一个处理结果的回调函数:
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年的更新。
你不能从异步函数中返回任何东西。 你可以回报的是一个承诺。 我解释了在这些问题的答案中承诺如何在jQuery中起作用:
如果你能解释你为什么要返回数据,以后你想怎么做,那么我可能会给你一个更具体的答案,如何做到这一点。
一般来说,而不是:
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之后,您的数据不会立即可用,因为它是异步的。 Promises对于函数来说是一个很好的抽象:我不能返回数据,因为我还没有它,我不想阻止并让你等待,所以这是一个承诺,而你可以稍后使用它,或者将它交给其他人并完成它。
看到这个DEMO 。
更新(2015年)
目前(截至2015年3月),jQuery Promises与Promises / A +规范不兼容,这意味着它们可能与其他Promises / A +一致性实现不能很好地协作。
然而,即将推出的3.x版本中的jQuery Promises 将与Promises / A +规范兼容(感谢Benjamin Gruenbaum指出)。 目前(截至2015年5月),jQuery的稳定版本是1.x和2.x.
我上面解释的(2011年3月)是一种使用jQuery Deferred Objects异步执行某些操作的方法,即在同步代码中可以通过返回一个值来实现。
但是同步函数调用可以做两件事 - 它可以返回一个值(如果可以的话)或抛出异常(如果它不能返回值)。 Promises / A +以同样代码中的异常处理功能强大的方式解决了这两种用例。 jQuery版本处理等价于返回一个值就好,但复杂异常处理的等价物有点问题。
特别是,同步代码中异常处理的要点不仅仅是放弃一个很好的消息,而是试图解决问题并继续执行,或者可能重新推出相同或不同的例外程序的其他部分处理。 在同步代码中,您有一个调用堆栈。 在异步调用中,您不需要按照Promises / A +规范的要求进行高级异常处理,这可以帮助您编写代码,即使对于复杂的用例,也能以有意义的方式处理错误和异常。
对于jQuery和其他实现之间的差异,以及如何将jQuery承诺转换为Promises / A +兼容,请参阅由Kris Kowal等人撰写的jQuery。 在Q库wiki和Promises上由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,请参阅:我可以使用:承诺。
更多信息请参阅:
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:Next Generations:更多的互操作性,Paul Krill提供的更少的Internet Explorer。
有趣的谈话
更新(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));
看到这个答案,看看为什么你应该总是使用拒绝处理程序的承诺:
当然,在这个例子中,你可以使用promise.then(alert)
因为你只是用与你的回调相同的参数调用alert
,但是箭头语法更通用,并且可以让你编写如下内容:
promise.then(data => alert("x is " + data.x));
并非所有的浏览器都支持这种语法,但是在某些情况下,您确定您的代码将运行在哪个浏览器上 - 例如,使用Electron,NW.js编写Chrome扩展程序,Firefox附加程序或桌面应用程序时,或AppJS(请参阅此答案以了解详细信息)。
有关箭头功能的支持,请参阅:
更新(2017)
现在有一种更新的语法,现在称为带有新的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
关键字创建的函数中使用它。 有关更多信息,请参阅:
有关浏览器的支持,请参阅:
有关Node的支持,请参阅:
在您没有async
本机支持的地方,请await
您使用Babel:
或者使用稍微不同的语法,如co
或Bluebird协程中的基于生成器的方法:
更多信息
有关承诺的更多详细信息的其他一些问题:
您可以将异步选项添加到false 并返回到ajax调用之外。
function testAjax() {
var result="";
$.ajax({
url:"getvalue.php",
async: false,
success:function(data) {
result = data;
}
});
return result;
}
链接地址: http://www.djcxy.com/p/9435.html
上一篇: jQuery: Return data after ajax call success
下一篇: Is there any reason to use a synchronous XMLHttpRequest?