0

在 jQuery 3(参见问题)中,它看起来像是改变progress$.when行为。当我的每个延期都得到解决时,我希望得到一个进度通知:

var urls = [
  'https://httpbin.org/delay/2',
  'https://httpbin.org/delay/1'
];
console.log('started');
var deferreds = $.map(urls, function(url) {
  var d = $.Deferred();
  $.ajax({
    url: url,
    type: 'GET'
  })
  .always(function(){
    console.log('done %o', url)
    d.notify();
    d.resolve.apply(this, arguments);
  });
  return d.promise();
});

$.when.apply(jQuery, deferreds).progress(function(){
  // Does not call
  console.log('progress?');
}).done(function(){
  console.log('all done');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>

代码也在codepen上。电流输出:

“开始”
“完成https://httpbin.org/delay/1
“完成https://httpbin.org/delay/2
“全部完成”

我希望progress?在每个完成的请求后看到一个输出。

当前的 jQuery API 有没有很好的方法来实现这种行为?

4

2 回答 2

1

允许组件承诺通知聚合承诺:

  • 不完全理性,
  • 鉴于它从未正常工作,很可能是 jQuery 1 和 2 中一个很少使用的功能。

考虑:

var urls = [
    'https://httpbin.org/delay/2',
    'https://httpbin.org/delay/1'
];
console.clear();
console.log('started');
var promises = urls.map(function(url, i) {
    return $.Deferred(function(d) {
        $.ajax({
            url: url,
            type: 'GET'
        })
        .always(function() {
            console.log('done', i, url);
            d.notify(i);
            d.resolve.apply(this, arguments);
        });
    }).promise();
});

$.when.apply(null, promises).progress(function(x) {
    console.log('progress ' + x);
}).done(function() {
    console.log('all done');
});

在 jQuery 1 或 2 中,您可以合理地期望:

“开始”
“完成 1 https://httpbin.org/delay/1
“进度 1”
“完成 0 https://httpbin.org/delay/2
“进度 0”
“全部完成”

但我得到:

“开始”
“完成 1 https://httpbin.org/delay/1
“进度未定义”
“完成 0 https://httpbin.org/delay/2
“进度 0”
“全部完成”

天知道那undefined是从哪里来的。

现在尝试交换两个网址的顺序 - 我得到:

“开始”
“完成 0 https://httpbin.org/delay/1
“进度 0”
“完成 1 https://httpbin.org/delay/2
“进度 0”
“全部完成”

仍然不如预期 - 现在你得到“进度 0”两次!

恕我直言,这个特性在 jQuery 3 中被删除并不奇怪。

于 2017-01-05T09:11:02.043 回答
0

您能否尝试使用以下代码:

var urls = [
  'https://httpbin.org/delay/2',
  'https://httpbin.org/delay/1'
];

console.log('started');
var deferreds = $.map(urls, function(url) {
  var d = $.Deferred();
  $.ajax({
    url: url,
    type: 'GET',
    success: function(){
      d.notify(); //notify the progress handler about the current progress
    } 
  })
  .always(function(){
    console.log('done %o', url)
    d.resolve.apply(this, arguments);
  });
  return d.promise();
});

$.when.apply(jQuery, deferreds).progress(function(){
  // Does not call
  console.log('progress?');
}).done(function(){
  console.log('all done');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div>
</div>

在这里,我们添加了success处理程序ajax,我们通过该处理程序调用deferred.notify(),通过该处理程序将调用进度

于 2017-01-05T05:00:12.813 回答