在Ajax中获取响应的问题

时间:2016-03-29 09:28:10

标签: javascript jquery ajax

我有以下代码:

  function f(){
      var value = "";
      var request1 = $.ajax({
           url : '/a',
           type: "GET"
      });
      var request2 = $.ajax({
          url: '/b', 
          type: 'GET',
      });

      $.when(request1, request2).done(function(result1, result2){

      //break point #1
      //result1 = [Object, "success", Object]
      //result2 = [Object, "success", Object]

      //do something
      })

     //break point #2
     //request1 = Object {readyState: 1}
     //request2 = Object {readyState: 1}

     return value
  }

当我在一个地方的断点上时,我得到result1 = [Object, "success", Object],而当我在另一个地方出来时,我得到request1 = Object {readyState: 1}。请参阅上文。

  1. 这个问题可能是什么原因?这是异步问题吗?
  2. 我想将返回值插入参数中。例如:a = f()。这是我应该做的回调吗?我试过阅读一些关于它的文章,但还没有设法实现它,所以我想得到一些帮助。我没有很多JavaScript经验,所以我还有一些难以实现的东西。

1 个答案:

答案 0 :(得分:2)

是的,这是因为异步功能。在调用返回后要执行的任何代码,无论是检查结果还是将返回值作为变量,都应放在回调中。在第2个断点处,您正在“跨越”异步呼叫,并且您无法控制此呼叫的状态。所以将所有代码放在回调中,即在断点1处。

将'f'函数的结果赋给变量,例如var r = f(),f取决于异步ajax调用,你需要将'f'函数转换为异步函数,例如通过使用jQuery的Deferred对象或使用ES6内置的promises。这样,您可以在f 解析时分配f的结果,这是所有ajax请求解析的时间。

在下面的代码片段中,我通过将异步函数替换为异步函数来模拟ajax调用,以将其转换为工作代码段。我将f转换为异步函数,让它返回一个Deferred对象。

$(document).ready(function() {
  function f() {
    var value = $.Deferred(); //this is the result this function will return
    
    //simulate ajax call 1
    var request1 = function() {
      var result = $.Deferred();
      result.resolve("this is the result of request 1");
      //result.reject("something went wrong in request 1");
      return result;
    };
    //simulate ajax call 2
    var request2 = function() {
      var result = $.Deferred();
      result.resolve("this is the result of request 2");
      //result.reject("something went wrong in request 2");
      return result;
    };

    $.when(request1(), request2()).done(function(result1, result2) {
      alert("result 1: " + result1);
      alert("result 2: " + result2);
      value.resolve(result1 + ' ' + result2); //assuming the result of the f function is a concatenation of both requests
    }).fail(function(err) {
      alert("error occurred while executing request 1 or 2: " + err);
      value.reject(err);
    });


    return value;
  }
  
  
  //call f function. Asign result asynchronously
  $.when(f()).done(function(result) {
    //f has 'resolved'
    alert("result of f: " + result);
  }).fail(function(err) {
    alert("error while executing f: " + err);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>