Javascript jQuery:ajax调用成功后返回数据
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5316697/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jQuery: Return data after ajax call success
提问by Francesco
I have something like this, where it is a simple call to a script that gives me back a value, a string..
我有这样的东西,它是对脚本的简单调用,它给我一个值,一个字符串..
function testAjax() {
$.ajax({
url: "getvalue.php",
success: function(data) {
return data;
}
});
}
but if I call something like this
但如果我这样称呼
var output = testAjax(svar); // output will be undefined...
so how can I return the value? the below code does not seem to work either...
那么我该如何返回值呢?下面的代码似乎也不起作用......
function testAjax() {
$.ajax({
url: "getvalue.php",
success: function(data) {
}
});
return data;
}
采纳答案by Guffa
The only way to return the data from the function would be to make a synchronous call instead of an asynchronous call, but that would freeze up the browser while it's waiting for the response.
从函数返回数据的唯一方法是进行同步调用而不是异步调用,但这会在浏览器等待响应时冻结。
You can pass in a callback function that handles the result:
您可以传入处理结果的回调函数:
function testAjax(handleData) {
$.ajax({
url:"getvalue.php",
success:function(data) {
handleData(data);
}
});
}
Call it like this:
像这样调用它:
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.
回答by rsp
Note: This answer was written in February 2010.
See updates from 2015, 2016 and 2017 at the bottom.
注意:此答案写于 2010 年 2 月。
请参阅底部的 2015、2016 和 2017 年更新。
You can't return anything from a function that is asynchronous. What you can return is a promise. I explained how promises work in jQuery in my answers to those questions:
您不能从异步函数返回任何内容。你能回报的是一个承诺。我在回答这些问题时解释了 jQuery 中的 Promise 是如何工作的:
- JavaScript function that returns AJAX call data
- jQuery jqXHR - cancel chained calls, trigger error chain
If you could explain whydo you want to return the data and what do you want to do with it later, then I might be able to give you a more specific answer how to do it.
如果您能解释为什么要返回数据以及稍后您想用它做什么,那么我可能会给您一个更具体的答案如何去做。
Generally, instead of:
通常,而不是:
function testAjax() {
$.ajax({
url: "getvalue.php",
success: function(data) {
return data;
}
});
}
you can write your testAjax function like this:
您可以像这样编写 testAjax 函数:
function testAjax() {
return $.ajax({
url: "getvalue.php"
});
}
Then you can get your promise like this:
然后你可以像这样得到你的承诺:
var promise = testAjax();
You can store your promise, you can pass it around, you can use it as an argument in function calls and you can return it from functions, but when you finally want to useyour data that is returned by the AJAX call, you have to do it like this:
您可以存储您的承诺,您可以传递它,您可以将其用作函数调用中的参数,也可以从函数中返回它,但是当您最终想要使用由 AJAX 调用返回的数据时,您必须像这样做:
promise.success(function (data) {
alert(data);
});
(See updates below for simplified syntax.)
(有关简化的语法,请参阅下面的更新。)
If your data is available at this point then this function will be invoked immediately. If it isn't then it will be invoked as soon as the data is available.
如果此时您的数据可用,则将立即调用此函数。如果不是,那么它将在数据可用时立即调用。
The whole point of doing all of this is that your data is not available immediately after the call to $.ajax because it is asynchronous. Promises is a nice abstraction for functions to say: I can't return you the data because I don't have it yet and I don't want to block and make you wait so here's a promiseinstead and you'll be able to use it later, or to just give it to someone else and be done with it.
执行所有这些操作的全部意义在于,您的数据在调用 $.ajax 后不会立即可用,因为它是异步的。Promises 是函数的一个很好的抽象,可以说:我无法返回数据,因为我还没有它,而且我不想阻塞并让你等待,所以这里是一个Promise,你将能够稍后使用它,或者只是将它交给其他人并完成它。
See this DEMO.
看到这个演示。
UPDATE (2015)
更新 (2015)
Currently (as of March, 2015) jQuery Promises are not compatible with the Promises/A+ specificationwhich means that they may not cooperate very well with other Promises/A+ conformant implementations.
目前(截至 2015 年 3 月)jQuery Promises 与Promises/A+ 规范不兼容,这意味着它们可能无法与其他Promises/A+ 一致性实现很好地合作。
However jQuery Promises in the upcoming version 3.x willbe compatible with the Promises/A+ specification (thanks to Benjamin Gruenbaumfor pointing it out). Currently (as of May, 2015) the stable versions of jQuery are 1.x and 2.x.
然而,即将发布的 3.x 版中的 jQuery Promises将与 Promises/A+ 规范兼容(感谢Benjamin Gruenbaum指出)。目前(截至 2015 年 5 月)jQuery 的稳定版本是 1.x 和 2.x。
What I explained above (in March, 2011) is a way to use jQuery Deferred Objectsto do something asynchronously that in synchronous code would be achieved by returning a value.
我在上面(2011 年 3 月)解释的是一种使用jQuery Deferred Objects异步执行某些操作的方法,在同步代码中可以通过返回值来实现。
But a synchronous function call can do two things - it can either return a value (if it can) or throw an exception (if it can't return a value). Promises/A+ addresses both of those use cases in a way that is pretty much as powerful as exception handling in synchronous code. The jQuery version handles the equivalent of returning a value just fine but the equivalent of complex exception handling is somewhat problematic.
但是同步函数调用可以做两件事——它可以返回一个值(如果可以)或抛出异常(如果它不能返回值)。Promises/A+ 以一种与同步代码中的异常处理一样强大的方式解决了这两个用例。jQuery 版本处理相当于返回一个值就好了,但相当于复杂的异常处理有点问题。
In particular, the whole point of exception handling in synchronous code is not just giving up with a nice message, but trying to fix the problem and continue the execution, or possibly rethrowing the same or a different exception for some other parts of the program to handle. In synchronous code you have a call stack. In asynchronous call you don't and advanced exception handling inside of your promises as required by the Promises/A+ specification can really help you write code that will handle errors and exceptions in a meaningful way even for complex use cases.
特别是,同步代码中的异常处理的重点不仅仅是放弃一个好的消息,而是试图解决问题并继续执行,或者可能为程序的其他部分重新抛出相同或不同的异常处理。在同步代码中,您有一个调用堆栈。在异步调用中,您不需要按照 Promises/A+ 规范的要求在 Promise 内部进行高级异常处理,这确实可以帮助您编写代码,即使对于复杂的用例,也能以有意义的方式处理错误和异常。
For differences between jQuery and other implementations, and how to convert jQuery promises to Promises/A+ compliant, see Coming from jQueryby Kris Kowal et al. on the Q library wiki and Promises arrive in JavaScriptby Jake Archibald on HTML5 Rocks.
有关 jQuery 和其他实现之间的差异,以及如何将 jQuery 承诺转换为 Promises/A+ 兼容,请参阅Kris Kowal 等人的来自 jQuery。在 Q library wiki 上,Promises在 HTML5 Rocks 上由 Jake Archibald在 JavaScript 中到达。
How to return a real promise
如何返回一个真正的承诺
The function from my example above:
我上面例子中的函数:
function testAjax() {
return $.ajax({
url: "getvalue.php"
});
}
returns a jqXHR object, which is a jQuery Deferred Object.
返回一个 jqXHR 对象,它是一个 jQuery Deferred Object。
To make it return a real promise, you can change it to - using the method from the Q wiki:
要使其返回真正的承诺,您可以将其更改为 - 使用Q wiki 中的方法:
function testAjax() {
return Q($.ajax({
url: "getvalue.php"
}));
}
or, using the method from the HTML5 Rocks article:
或者,使用HTML5 Rocks 文章中的方法:
function testAjax() {
return Promise.resolve($.ajax({
url: "getvalue.php"
}));
}
This Promise.resolve($.ajax(...))
is also what is explained in the promise
module documentationand it should work with ES6 Promise.resolve()
.
这Promise.resolve($.ajax(...))
也是模块文档中解释的promise
内容,它应该适用于ES6Promise.resolve()
。
To use the ES6 Promises today you can use es6-promise module's polyfill()
by Jake Archibald.
今天要使用 ES6 Promises,您可以使用Jake Archibald 的es6-promise 模块polyfill()
。
To see where you can use the ES6 Promises without the polyfill, see: Can I use: Promises.
要查看不带 polyfill 的 ES6 Promises 可以在何处使用,请参阅:我可以使用:Promises 吗。
For more info see:
有关更多信息,请参阅:
- 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/
- 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/
Future of jQuery
jQuery 的未来
Future versions of jQuery (starting from 3.x - current stable versions as of May 2015 are 1.x and 2.x) will be compatible with the Promises/A+ specification(thanks to Benjamin Gruenbaumfor pointing it out in the comments). "Two changes that we've already decided upon are Promise/A+ compatibility for our Deferred implementation [...]"(jQuery 3.0 and the future of Web development). For more info see: jQuery 3.0: The Next Generationsby Dave Methvin and jQuery 3.0: More interoperability, less Internet Explorerby Paul Krill.
jQuery 的未来版本(从 3.x 开始 - 截至 2015 年 5 月的当前稳定版本为 1.x 和 2.x)将与Promises/A+ 规范兼容(感谢Benjamin Gruenbaum在评论中指出)。“我们已经决定的两个变化是我们的延迟实现的 Promise/A+ 兼容性 [...]”(jQuery 3.0 和 Web 开发的未来)。有关更多信息,请参阅:Dave Methvin 的jQuery 3.0:下一代和Paul Krill 的jQuery 3.0:更多的互操作性,更少的 Internet Explorer。
Interesting talks
有趣的谈话
- Boom, Promises/A+ Was Bornby Domenic Denicola (JSConfUS 2013)
- Redemption from Callback Hellby Michael Hymanson and Domenic Denicola (HTML5DevConf 2013)
- JavaScript Promisesby David M. Lee (Nodevember 2014)
- Boom, Promises/A+ 诞生于 Domenic Denicola (JSConfUS 2013)
- Michael Hymanson 和 Domenic Denicola从回调地狱中救赎(HTML5DevConf 2013)
- David M. Lee 的JavaScript Promises(Nodevember 2014)
UPDATE (2016)
更新 (2016)
There is a new syntax in ECMA-262, 6th Edition, Section 14.2called arrow functionsthat may be used to further simplify the examples above.
ECMA-262,第 6 版,第 14.2 节中有一种称为箭头函数的新语法,可用于进一步简化上述示例。
Using the jQuery API, instead of:
使用 jQuery API,而不是:
promise.success(function (data) {
alert(data);
});
you can write:
你可以写:
promise.success(data => alert(data));
or using the Promises/A+ API:
或使用 Promises/A+ API:
promise.then(data => alert(data));
Remember to always use rejection handlers either with:
请记住始终使用拒绝处理程序:
promise.then(data => alert(data), error => alert(error));
or with:
或与:
promise.then(data => alert(data)).catch(error => alert(error));
See this answer to see why you should always use rejection handlers with promises:
请参阅此答案以了解为什么您应该始终使用带有承诺的拒绝处理程序:
Of course in this example you could use just promise.then(alert)
because you're just calling alert
with the same arguments as your callback, but the arrow syntax is more general and lets you write things like:
当然,在这个例子中,你可以使用,promise.then(alert)
因为你只是alert
使用与回调相同的参数进行调用,但箭头语法更通用,可以让你编写如下内容:
promise.then(data => alert("x is " + data.x));
Not every browser supports this syntax yet, but there are certain cases when you're sure what browser your code will run on - e.g. when writing a Chrome extension, a Firefox Add-on, or a desktop application using Electron, NW.js or AppJS (see this answerfor details).
并非每个浏览器都支持这种语法,但在某些情况下,您可以确定代码将在哪个浏览器上运行 - 例如,在编写Chrome 扩展程序、Firefox 插件或使用 Electron、NW.js 或AppJS(有关详细信息,请参阅此答案)。
For the support of arrow functions, see:
有关箭头函数的支持,请参阅:
- http://caniuse.com/#feat=arrow-functions
- http://kangax.github.io/compat-table/es6/#test-arrow_functions
- http://caniuse.com/#feat=arrow-functions
- http://kangax.github.io/compat-table/es6/#test-arrow_functions
UPDATE (2017)
更新 (2017)
There is an even newer syntax right now called async functions with a new await
keyword that instead of this code:
现在有一种更新的语法称为 async 函数,它带有一个 newawait
关键字,而不是以下代码:
functionReturningPromise()
.then(data => console.log('Data:', data))
.catch(error => console.log('Error:', error));
lets you write:
让你写:
try {
let data = await functionReturningPromise();
console.log('Data:', data);
} catch (error) {
console.log('Error:', error);
}
You can only use it inside of a function created with the async
keyword. For more info, see:
您只能在使用async
关键字创建的函数内部使用它。有关更多信息,请参阅:
- 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
- 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
For support in browsers, see:
有关浏览器的支持,请参阅:
For support in Node, see:
有关 Node 的支持,请参阅:
In places where you don't have native support for async
and await
you can use Babel:
在你没有原生支持的地方async
,await
你可以使用 Babel:
or with a slightly different syntax a generator based approach like in co
or Bluebird coroutines:
或者使用稍微不同的语法基于生成器的方法,例如 inco
或 Bluebird 协程:
More info
更多信息
Some other questions about promises for more details:
有关 promise 的其他一些问题以获取更多详细信息:
- promise call separate from promise-resolution
- Q Promise delay
- Return Promise result instead of Promise
- Exporting module from promise result
- What is wrong with promise resolving?
- Return value in function from a promise block
- How can i return status inside the promise?
- Should I refrain from handling Promise rejection asynchronously?
- Is the deferred/promise concept in JavaScript a new one or is it a traditional part of functional programming?
- How can I chain these functions together with promises?
- Promise.all in JavaScript: How to get resolve value for all promises?
- Why Promise.all is undefined
- function will return null from javascript post/get
- Use cancel() inside a then-chain created by promisifyAll
- Why is it possible to pass in a non-function parameter to Promise.then() without causing an error?
- Implement promises pattern
- Promises and performance
- Trouble scraping two URLs with promises
- http.request not returning data even after specifying return on the 'end' event
- async.each not iterating when using promises
- jQuery jqXHR - cancel chained calls, trigger error chain
- Correct way of handling promisses and server response
- Return a value from a function call before completing all operations within the function itself?
- Resolving a setTimeout inside API endpoint
- Async wait for a function
- JavaScript function that returns AJAX call data
- try/catch blocks with async/await
- jQuery Deferred not calling the resolve/done callbacks in order
- Returning data from ajax results in strange object
- javascript - Why is there a spec for sync and async modules?
- 承诺调用与承诺解析分开
- Q 承诺延迟
- 返回 Promise 结果而不是 Promise
- 从承诺结果导出模块
- 承诺解决有什么问题?
- 从承诺块返回函数中的值
- 我如何在承诺内返回状态?
- 我应该避免异步处理 Promise 拒绝吗?
- JavaScript 中的延迟/承诺概念是一个新概念还是函数式编程的传统部分?
- 如何将这些功能与承诺链接在一起?
- JavaScript 中的 Promise.all:如何获取所有 Promise 的解析值?
- 为什么 Promise.all 未定义
- 函数将从 javascript post/get 返回 null
- 在由 promisifyAll 创建的 then 链中使用 cancel()
- 为什么可以将非函数参数传递给 Promise.then() 而不会导致错误?
- 实现承诺模式
- 承诺和业绩
- 使用 Promise 抓取两个 URL 时遇到问题
- 即使在“结束”事件上指定返回后,http.request 也不返回数据
- 使用承诺时 async.each 不迭代
- jQuery jqXHR - 取消链式调用,触发错误链
- 处理承诺和服务器响应的正确方法
- 在完成函数本身内的所有操作之前从函数调用返回一个值?
- 解决 API 端点内的 setTimeout
- 异步等待函数
- 返回 AJAX 调用数据的 JavaScript 函数
- 使用 async/await 尝试/捕获块
- jQuery Deferred 没有按顺序调用解析/完成回调
- 从ajax返回数据导致奇怪的对象
- javascript - 为什么有同步和异步模块的规范?
回答by Ging3r
you can add async option to false andreturn outside the ajax call.
您可以将 async 选项添加到 false并在 ajax 调用之外返回。
function testAjax() {
var result="";
$.ajax({
url:"getvalue.php",
async: false,
success:function(data) {
result = data;
}
});
return result;
}
回答by user1509803
Idk if you guys solved it but I recommend another way to do it, and it works :)
Idk 如果你们解决了它,但我推荐另一种方法来做到这一点,它有效:)
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;
}
})
So the main idea here is that, by adding async: false, then you make everything waits until the data is retrieved. Then you assign it to a static variable of the class, and everything magically works :)
所以这里的主要思想是,通过添加 async: false,然后你让一切都等待,直到数据被检索。然后你将它分配给类的一个静态变量,一切都神奇地工作:)
回答by Techism
See jquery docs example: http://api.jquery.com/jQuery.ajax/(about 2/3 the page)
请参阅 jquery 文档示例:http: //api.jquery.com/jQuery.ajax/(大约页面的 2/3)
You may be looking for following code:
您可能正在寻找以下代码:
$.ajax({
url: 'ajax/test.html',
success: function(data) {
$('.result').html(data);
alert('Load was performed.');
}
});
Same page...lower down.
同一页……往下。