jQuery。ajax调用成功后返回数据

我有这样的东西,它是一个简单的调用脚本,给我返回一个值,一个字符串。

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

**注意:这个答案写于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之后,你的数据并不是立即可用的,因为它是异步的。许诺是一个很好的抽象,可以让函数说。我不能把数据返回给你,因为我还没有得到它,我不想阻塞并让你等待,所以这里有一个承诺,你以后可以使用它,或者直接把它交给别人,就可以了。 请看这个[DEMO](http://jsfiddle.net/jW68r/)。 更新(2015)

目前(截至2015年3月)jQuery Promises与Promises/A+规范不兼容,这意味着他们可能不会与其他Promises/A+符合的实现合作得很好。 然而jQuery Promises在即将到来的3.x版本中**将与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+的承诺,请参见Q库维基上Kris Kowal等人的Coming from jQuery和HTML5 Rocks上Jake Archibald的Promises arrive in JavaScript

如何返回一个真正的承诺

我上面例子中的那个函数。

function testAjax() {
  return $.ajax({
      url: "getvalue.php"
  });
}

返回一个jqXHR对象,它是一个jQuery的延迟对象。 为了让它返回一个真正的承诺,你可以把它改为--使用Q wiki的方法

function testAjax() {
  return Q($.ajax({
      url: "getvalue.php"
  }));
}

或者,使用【HTML5 Rocks文章中的方法】(http://www.html5rocks.com/en/tutorials/es6/promises/#toc-javascript-promises)。

function testAjax() {
  return Promise.resolve($.ajax({
      url: "getvalue.php"
  }));
}

这个Promise.resolve($.ajax(...))也是promise模块文档中解释的,它应该与ES6Promise.resolve()一起工作。 今天要使用ES6承诺,你可以使用Jake Archibald的[es6-promise模块'的polyfill()](https://github.com/jakearchibald/es6-promise#auto-polyfill)。 要想知道在哪里可以使用没有polyfill的ES6 Promises,请看。Can I use: Promises。 更多信息见。

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(data => alert("x is " + data.x));

目前还不是每个浏览器都支持这种语法,但在某些情况下,你可以确定你的代码将在哪个浏览器上运行--例如,在编写Chrome扩展Firefox插件或使用Electron、NW.js或AppJS的桌面应用时(详见本答案)。 关于对箭头函数的支持,见。

  • 现在有一种更新的语法,叫做async函数,有一个新的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 "关键字创建的函数中使用它。欲了解更多信息,请参见。

评论(9)
解决办法

从函数中返回数据的唯一方法是进行同步调用,而不是异步调用,但这将使浏览器在等待响应时陷入僵局。

你可以传入一个处理结果的回调函数。

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.
评论(7)

见jquery docs的例子。 http://api.jquery.com/jQuery.ajax/ (大约2/3的页面)

你可能要找的是以下代码。

    $.ajax({
     url: 'ajax/test.html',
     success: function(data) {
     $('.result').html(data);
     alert('Load was performed.');
   }
});

同一页......在下面。

评论(0)