【问题标题】:Why is my jQuery promise resolving immediately?为什么我的 jQuery 承诺会立即解决?
【发布时间】:2019-02-08 11:31:59
【问题描述】:

使用 jQuery 承诺,我正在尝试:

  1. 为(动物的)所有可能值调用 API
  2. 为每只动物(动物声音)调用 API 方法
  3. 当每个动物的声音恢复时通知 - 假设需要一段时间才能解决
  4. 返回所有动物声音时通知

我将所有动物声音函数放入一个数组中,然后调用$.when()。我希望在所有动物的声音都返回后解决此问题,但我发现它会立即解决。有谁知道我做错了什么?

function () {
  $('#txtNotification').text('Started ....');

  $.ajax({
    url: "/api/animals/all"
  }).done(function(data) {
    var animalFunctions = [];

    for (var animalType of data) {
      var animalFunction = $.ajax({
        url: "/api/animal/sound/" + animalType
      }).done(function(data) {
        $('#txtNotification').text(data);
      });

      animalFunctions.push(animalFunction);
    }

    $.when(animalFunctions).then(function() {
      $('#txtNotification').text('Done.');
    });
  });
}

【问题讨论】:

  • $.when()cannot accept an array 为数不多的 jQuery 函数之一
  • 添加到@MTCoster 的评论,尝试将$.when(animalFunctions) 更改为$.when(...animalFunctions)。扩展运算符 (...) 可以将您的数组转换为参数列表。
  • 这就是我推荐的。 ES6 之前的解决方案是 $.when.apply($, animalFunctions)
  • @MTCoster。杰出的。那行得通。我永远不会得到那个。如果您将其写为答案,我将投票并接受。感谢您的帮助

标签: jquery ajax promise


【解决方案1】:

$.when()cannot accept an array 为数不多的 jQuery 函数之一 - 您需要将每个 Promise 作为单独的参数调用它:

ES6 方式:

$.when(...animalFunctions).then(() => {
  $('#txtNotification').text('Done.');
});

石器时代的方式:

$.when.apply($, animalFunctions).then(function () {
  $('#txtNotification').text('Done.');
});

【讨论】:

    【解决方案2】:

    jQuery 的Deferred.promise() 允许您“通知”各个项目的进度。

    var $def = jQuery.Deferred();
    
    $.ajax({
      url: "https://jsonplaceholder.typicode.com/users"
    })
    .done(function getUsersAsync(users) {
      for (var user of users) {
        $def.notify(`Fetching comments of ${user.username}, ID: ${user.id}`);
        
        $.ajax({
          url: "https://jsonplaceholder.typicode.com/comments",
          data: JSON.stringify({ id: user.id })
        })
        .done(function (arg) {
          // Do stuff with the comments here
        });
      }
      
      $def.resolve(users.length);
    })
    .fail(function () {
      $def.reject('ERR: Failed retrieving comments');
    });
    
    
    $def
      .progress(function (message) {
        console.log(message);
      })
      .done(function (count) {
        console.log('ALL DONE. Total user: ' + count);
      });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

    【讨论】:

      【解决方案3】:

      return: false 添加到传递给.done() 的匿名函数中。看看有没有帮助。

      function () {
              $('#txtNotification').text('Started ....');
      
              $.ajax({
                      url: "/api/animals/all"
                  })  
                  .done(function( data ) {
      
                      var animalFunctions = [];
      
                      for (var animalType of data) {
      
                          var animalFunction = $.ajax({
                                  url: "/api/animal/sound/" + animalType
                              })
                              .done(function(data) {
                                  $('#txtNotification').text(data);
                                  return false;
                              }
                          );
      
                          animalFunctions.push(animalFunction);
                      }
      
                      $.when(animalFunctions).then(function() {
                          $('#txtNotification').text('Done.');
                      });
                  });
          }
      

      【讨论】:

      • 感谢您的回复。但这并没有奏效。干杯
      猜你喜欢
      • 2015-11-11
      • 1970-01-01
      • 1970-01-01
      • 2018-11-17
      • 1970-01-01
      • 1970-01-01
      • 2018-07-09
      • 2015-11-10
      • 1970-01-01
      相关资源
      最近更新 更多