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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 16:37:34  来源:igfitidea点击:

jQuery: Return data after ajax call success

javascriptjqueryajax

提问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 是如何工作的:

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 promisemodule 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:

有关更多信息,请参阅:

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

有趣的谈话

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 alertwith 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:

有关箭头函数的支持,请参阅:

UPDATE (2017)

更新 (2017)

There is an even newer syntax right now called async functions with a new awaitkeyword 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 asynckeyword. For more info, see:

您只能在使用async关键字创建的函数内部使用它。有关更多信息,请参阅:

For support in browsers, see:

有关浏览器的支持,请参阅:

For support in Node, see:

有关 Node 的支持,请参阅:

In places where you don't have native support for asyncand awaityou can use Babel:

在你没有原生支持的地方asyncawait你可以使用 Babel:

or with a slightly different syntax a generator based approach like in coor Bluebird coroutines:

或者使用稍微不同的语法基于生成器的方法,例如 inco或 Bluebird 协程:

More info

更多信息

Some other questions about promises for more details:

有关 promise 的其他一些问题以获取更多详细信息:

回答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.

同一页……往下。