jQuery:在Ajax调用成功后返回数据

这个问题在这里已经有了答案:

  • 如何返回来自异步调用的响应? 33个答案

  • 从函数中返回数据的唯一方法是进行同步调用而不是异步调用,但这会在浏览器等待响应时冻结浏览器。

    你可以传递一个处理结果的回调函数:

    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中起作用:

  • 返回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之后,您的数据不会立即可用,因为它是异步的。 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,请参阅:我可以使用:承诺。

    更多信息请参阅:

  • 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:Next Generations:更多的互操作性,Paul Krill提供的更少的Internet Explorer。

    有趣的谈话

  • Boom,Promises / A +由Domenic Denicola出生(JSConfUS 2013)
  • 迈克尔杰克逊和多梅尼克丹尼科拉回拨地狱(HTML5DevConf 2013)
  • JavaScript的承诺David M. Lee(Nodevember 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));
    

    看到这个答案,看看为什么你应该总是使用拒绝处理程序的承诺:

  • 我是否应该避免异步处理Promise拒绝?
  • 当然,在这个例子中,你可以使用promise.then(alert)因为你只是用与你的回调相同的参数调用alert ,但是箭头语法更通用,并且可以让你编写如下内容:

    promise.then(data => alert("x is " + data.x));
    

    并非所有的浏览器都支持这种语法,但是在某些情况下,您确定您的代码将运行在哪个浏览器上 - 例如,使用Electron,NW.js编写Chrome扩展程序,Firefox附加程序或桌面应用程序时,或AppJS(请参阅此答案以了解详细信息)。

    有关箭头功能的支持,请参阅:

  • http://caniuse.com/#feat=arrow-functions
  • http://kangax.github.io/compat-table/es6/#test-arrow_functions
  • 更新(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关键字创建的函数中使用它。 有关更多信息,请参阅:

  • 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
  • 有关浏览器的支持,请参阅:

  • http://caniuse.com/async-functions
  • 有关Node的支持,请参阅:

  • http://node.green/#ES2017-features-async-functions
  • 在您没有async本机支持的地方,请await您使用Babel:

  • https://babeljs.io/docs/plugins/transform-async-to-generator/
  • 或者使用稍微不同的语法,如co或Bluebird协程中的基于生成器的方法:

  • https://www.npmjs.com/package/co
  • http://bluebirdjs.com/docs/api/promise.coroutine.html
  • 更多信息

    有关承诺的更多详细信息的其他一些问题:

  • 承诺与承诺解决分离
  • Q承诺延迟
  • 返回Promise结果而不是Promise
  • 从诺言结果导出模块
  • 诺言解决有什么问题?
  • 从promise块返回函数中的值
  • 我如何返回承诺内的状态?
  • 我是否应该避免异步处理Promise拒绝?
  • JavaScript中的延期/承诺概念是一个新概念吗?还是传统的函数式编程?
  • 我如何将这些功能与承诺一起链接起来?
  • Promise.all在JavaScript中:如何获得所有承诺的解决价值?
  • 为什么Promise.all是未定义的
  • 函数将从javascript post / get返回null
  • 在promisifyAll创建的then-chain链中使用cancel()
  • 为什么有可能将一个非函数参数传递给Promise.then()而不会导致错误?
  • 实施承诺模式
  • 承诺和表现
  • 用承诺解决两个URL的问题
  • 即使在指定'结束'事件返回后,http.request也不会返回数据
  • async.each在使用promise时不会迭代
  • jQuery jqXHR - 取消链接调用,触发错误链
  • 处理promisses和服务器响应的正确方法
  • 在完成函数本身内的所有操作之前,从函数调用中返回一个值?
  • 解决API端点内的setTimeout问题
  • 异步等待一个函数
  • 返回AJAX调用数据的JavaScript函数
  • 尝试/ catch异步/等待块
  • jQuery延迟不按顺序调用解析/完成回调
  • 从Ajax返回数据会导致奇怪的对象
  • javascript - 为什么有同步和异步模块的规范?

  • 您可以将异步选项添加到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?