jQuery .done没有按预期返回

时间:2016-06-20 16:33:45

标签: javascript jquery ajax promise

我知道这是我的一个误解,我正在努力去了解我做错了什么,我真的可以使用一些帮助。

我有一个成功的ajax请求并且返回数据就好了。 Api返回一个错误代码,然后我尝试根据给出的代码返回一个响应,除了该函数只返回ajax调用传递的内容。

function getData(){
    var promise = $.ajax({
       url: 'api.php',
       type: 'POST',
       dataType: 'json'
    });
    return promise.done(function(data){
        console.log(data);
        if(data.errorCode === 0){
            return data;
        } else {
            return 'failed';
        }
    });
}
$(document).ready(function(){
   $('.btn').click(function(){
       var apiData = getData();
       console.log(apiData);
   });
});

因此,如果api返回的错误代码不是0,那么函数getData应该返回一个'failed'字符串,除了它返回数据元素。我知道代码不是0,因为console.log显示代码是999.我做错了什么?为什么我不能让它返回我的“失败”字符串?

2 个答案:

答案 0 :(得分:4)

getData没有(也不能)返回数据或"failed";它返回承诺。你使用getData内的方式消费了这个承诺:

$(document).ready(function(){
   $('.btn').click(function(){
       getData().done(function(apiData) {   // **
           console.log(apiData);            // **
       });                                  // **
   });
});

在该回调中,apiData将是getData中返回的回调,因此它将是数据对象或字符串"failed"

(我在那里使用done,因为它是你在别处使用的,但通常我会使用标准的promise函数then。)

了解承诺的关键事项之一是then(和done)会返回新承诺(从技术上讲,有了真正的承诺,可以)将根据回调的内容进行结算。

所以考虑一下(让我们坚持使用jQuery的Deferred)

function doSomething() {
  var d = $.Deferred();
  setTimeout(function() {
    // Resolve our promise with "a"
    d.resolve("a");
  }, 10);
  return d.promise();
}

// Consume the promise and put it through a chain:
doSomething()
  .then(function(result) {
    // This callback happens to do synchronous processing
    console.log("First callback got", result);
    return result.toUpperCase();
  })
  .then(function(result) {
    // This one does something async, and so it returns a promise
    var cd = $.Deferred();
    setTimeout(function() {
      console.log("Second callback got", result);
      cd.resolve(result + result);
    }, 10);
    return cd.promise();
  })
  .then(function(result) {
    console.log("Third callback got", result);
  });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

输出是

First callback got a
Second callback got A
Third callback got AA

现在,早些时候我说then总是返回一个承诺(可以)。当我的第一个回调是同步并直接返回一个值时,它是如何做到的,但我的第二个回调是异步并返回一个承诺? then函数查看回调的返回值,如果它是“thenable”(其上带有then的东西),则返回它;如果它不可用,它会创建一个新的,已解决的承诺,其值为分辨率值。

为了完整起见,以上是本地JavaScript承诺的示例(需要浏览器支持):

function doSomething() {
  return new Promise(function(resolve) {
    setTimeout(function() {
      // Resolve our promise with "a"
      resolve("a");
    }, 10);
  });
}

// Consume the promise and put it through a chain:
doSomething()
  .then(function(result) {
    // This callback happens to do synchronous processing
    console.log("First callback got", result);
    return result.toUpperCase();
  })
  .then(function(result) {
    // This one does something async, and so it returns a promise
    return new Promise(function(resolve) {
      setTimeout(function() {
        console.log("Second callback got", result);
        resolve(result + result);
      }, 10);
    });
  })
  .then(function(result) {
    console.log("Third callback got", result);
  });

输出是

First callback got a
Second callback got A
Third callback got AA

答案 1 :(得分:0)

根据http://api.jquery.com/jquery.ajax/文档,您可以链接.done, .fail, .always or .then

$(document).ready(function() {
  $('.btn').click(function() {
    $.ajax({
       url: 'api.php',
       type: 'POST',
       dataType: 'json'
    })
    .done(function(data) {
        console.log(data);
        if (data.errorCode === 0) {
            console.log(data)
        } else {
            console.log(data)
        }
    });
  });
});

这将有效