问题:

我一直在摸索,试图弄清楚为什么我使用$ .when.apply()。then()编写了一些代码来解析多个promise,然后返回数据似乎不同步,返回了未解决的承诺,然后在调用回调后解决承诺。

这是我一直在使用的模拟代码:



format(function(r) {
	console.log('Done!', r);
});

function format(callback) {
	var promises = [];
  var items = [
  {model: 'George'}
  ];

  $.each(items, function (i, item) {
        var selectedSeries = item.model;
        promises.push(getSeriesDescription(selectedSeries));
    });

    $.when.apply($, promises).then(function (seriesInfo) {
    		console.log('Calling back');
        callback(seriesInfo);
    });
}

function getSeriesDescription(series) {
	return new Promise(function (resolve, reject) {
        getSeriesNotes().then(function (notes) {
            console.log('Processing Notes...');
            var rNotes;
            $.each(notes.data, function () {
                if (series !== 'undefined') {
                    console.log('Checking series ' + this.first_name + ' against ' + series + '...');
                    if (this.first_name == series) {
                        console.log('Series found!');
                        rNotes = this;
                        return false;
                    }
                }
            });
            if (rNotes !== undefined) {
                console.log('Returning series specific notes...');
                resolve(rNotes);
            } else {
                resolve(notes);
            }
        });
    });
}

function getSeriesNotes() {

    return $.ajax({
        url: 'https://reqres.in/api/users?delay=2',
        dataType: 'json',
        type: 'GET',
        data: '',
    });
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>





我发现了什么:

经过无数次调试,我终于意识到意外的行为似乎是我使用的jQuery版本的结果。下面,我有两个小提琴,它们的代码完全相同,但版本不同。 (我发布了jsfiddles,因为StackOverflow的没有jQuery 3.x版本)

jQuery 2.1.3:

https://jsfiddle.net/persononfire/1epgnfuh/2/

jQuery 3.1.1:

https://jsfiddle.net/persononfire/a9gc0y14/

通过查看控制台,您将看到v3版本返回的每个版本,而v2版本却没有。

预期结果:


  加工说明...
  
  (索引):58检查乔治对阵乔治...
  
  (索引):找到60个系列!
  
  (索引):67返回系列特定说明...
  
  (索引):46回电
  
  (索引):31完成! {id:1,first_name:“ George”,last_name:“ Bluth”,头像:“ https://s3.amazonaws.com/uifaces/faces/twitter/calebogden/128.jpg”}


版本2.1.3首先返回最后两行,然后按我期望的顺序返回其他所有内容。

问题:

所以我的问题是;为什么两个版本的jQuery在结果上有所不同?我在版本文档中找不到任何看起来像是会导致jQuery的两个版本之间行为不同的东西。

我很高兴对此有任何见识,对我有启发。

最佳答案

jQuery v2的Deferred和Promise不符合Promises / A +规范(部分是因为它们早于当前版本),并且不能与本机Promises可靠地互操作。 jQuery v3 fixed them,因此它们可以与本机promise互操作。 (尽管$.when并不完全兼容。)

另外:如果您要处理本机承诺,我建议尽量远离$.when。请改用Promise.all。 :-)实际上,我的偏好是要么完全停留在jQuery Deferred / Promise生态系统之内,要么完全停留在它之外(通过尽早将所有jQuery Deferreds / Promises转换为真实的)。

这是$.when不能使用本机Promise的一个更简单的示例。

jQuery v2,不起作用:



function timeout(value, delay) {
  console.log("creating promise for " + value);
  return new Promise(resolve => {
    setTimeout(() => {
      console.log("resolving promise for " + value);
      resolve(value);
    }, delay);
  });
}

$.when(
  timeout(1, 100),
  timeout(2, 200),
  timeout(3, 300)
).then(result => {
  console.log("then on $.when: ", result);
});

.as-console-wrapper {
  max-height: 100% !important;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>





jQuery v3,可以工作,但请注意返回值只是第一个promise的值(因为$.whenthen回调的调用是非标准的:它将每个promise结果作为离散参数传递):



function timeout(value, delay) {
  console.log("creating promise for " + value);
  return new Promise(resolve => {
    setTimeout(() => {
      console.log("resolving promise for " + value);
      resolve(value);
    }, delay);
  });
}

$.when(
  timeout(1, 100),
  timeout(2, 200),
  timeout(3, 300)
).then(result => {
  console.log("then on $.when: ", result);
});

.as-console-wrapper {
  max-height: 100% !important;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>







旁注:没有必要在new Promise中使用getSeriesDescriptiongetSeriesNotes().then已经向您保证可以使用。有趣的是,如果您解决了该问题,它甚至可以在jQuery v2中使用:



format(function(r) {
  console.log('Done!', r);
});

function format(callback) {
  var promises = [];
  var items = [{
    model: 'George'
  }];

  $.each(items, function(i, item) {
    var selectedSeries = item.model;
    promises.push(getSeriesDescription(selectedSeries));
  });

  $.when.apply($, promises).then(function(seriesInfo) {
    console.log('Calling back');
    callback(seriesInfo);
  });
}

function getSeriesDescription(series) {
  return getSeriesNotes().then(function(notes) {
    console.log('Processing Notes...');
    var rNotes;
    $.each(notes.data, function() {
      if (series !== 'undefined') {
        console.log('Checking series ' + this.first_name + ' against ' + series + '...');
        if (this.first_name == series) {
          console.log('Series found!');
          rNotes = this;
          return false;
        }
      }
    });
    if (rNotes !== undefined) {
      console.log('Returning series specific notes...');
      return rNotes;
    } else {
      return notes;
    }
  });
}

function getSeriesNotes() {

  return $.ajax({
    url: 'https://reqres.in/api/users?delay=2',
    dataType: 'json',
    type: 'GET',
    data: '',
  });
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

关于javascript - 在jQuery 2.1(而非3.1)中解决了 promise 之前,返回了多个 promise 之后的回调,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50863790/

10-12 00:09
查看更多