为什么 deferred 的 'then' 回调先于 nested AJAX 的成功回调触发?

Why is the deferred's 'then' callback triggered before nested AJAX's success callback?

我是 jQuery promises 的新手,我无法成功地完成我 认为 可能实现的事情。我有一个 AJAX 请求传递到 when。在该请求的成功回调中,我发出 second AJAX 请求并将 returned 承诺分配给我传递给 [=13= 的变量] 我 return 来自成功回调。 Here is a fiddle of the below code.

Item = function(data) {
    this.name = data.name;
    this.price = data.price;
    this.cost = data.cost;
}

$(function() {

  var rec = new Item({
    name: '',
    price: 0,
    cost: 0
  });

    $.when($.ajax({
      url: '/echo/json',
      //url: '/error',
      success: function() {

        rec.name = 'Item1';

        // Get price
        var p1 = $.ajax({
            url: '/echo/json',
          success: function() {
            rec.price = 999.99; // I expect to see the price rendered as 999.99
          }
        });

        return $.when(p1);

      },
      error: function() {

        rec.name = 'NULL';

      }
    })
  ).then(function() {
        $('#resultText').css('color', 'green').append('ITEM UPDATE SUCCESS');
        $('#name').text(rec.name);
        $('#price').text(rec.price);
      $('#cost').text(rec.cost);
  }, function() {
        $('#resultText').css('color', 'red').append('ITEM UPDATE FAILURE');
        $('#price').text(rec.price);
      $('#cost').text(rec.cost);
  });
})

当你 运行 fiddle 时,我不明白为什么呈现的 "price" 不是 999.99。为什么 p1 在成功回调 运行 之前解析?需要改变什么才能满足我的期望?

您的 promise 链一团糟,您的意图也很不明确,所以这里有一个大致基于您的代码的示例,以演示如何使事情更容易理解。

$.ajax({url: '/echo/json'}) //do one request
    .then(function(resultFromServer){
            //yay! 1st request was successful
            return $.ajax({url: '/echo/json'}); //then do another request
        },function(err){
            //something went wrong with the AJAX

            //rethrow to let the next "catch" pick this up, skipping further "then" clauses
            throw err;
        })
    .then(function(resultFromServer) {
            rec.price=999.99; //yay! success again
            //...
        },function() {
            //something went wrong
        });