Могу ли я передавать промисы в jQuery.when() или только отложенные?

В документации для jQuery.when() сказано, что эта функция принимает Deferreds. Тем не менее, он также говорит позже, что:

Если в jQuery.when() передается один аргумент, и он не является отложенным или обещанным...

что, по-видимому, подразумевает, что он также может принимать обещания. Но промисы не являются отложенными — у них есть подмножество методов отложенных. Я думаю, вы могли бы сказать, что Deferred — это Promise, но Promise — это не Deferred.

Вопросы:

  1. Может ли $.when() принимать обещания или отсрочки? Кажется, это работает в моем тестировании.
  2. Есть ли ошибка в документе? Я думаю, следует сказать, что $.when() принимает обещания, а не только отложенные.

person Jonathan Aquino    schedule 05.04.2016    source источник
comment
1. Да, может. 2. Лучше спросить у разработчиков jQuery.   -  person Karl-André Gagnon    schedule 05.04.2016
comment
@Karl-AndréGagnon 2. Хорошая идея - я зарегистрировал эту ошибку документации jquery: github .com/jquery/api.jquery.com/issues/906   -  person Jonathan Aquino    schedule 05.04.2016
comment
@JonathanAquino $.when() может принимать jQuery.Deferred(), jQuery.promise() или собственный Promise. См. blog.jquery.com/2016/01/ 14/jquery-3-0-beta-released . Документация в $.when() пытается описать, что $.when() может принимать параметр, который не является объектом обещания jQuery.Deferred(), jQuery или собственным Promise, а обратные вызовы .then() или .done() будут обрабатывать переданный параметр как разрешение jQuery.Deferred()   -  person guest271314    schedule 05.04.2016
comment
@JonathanAquino Возможно, есть несколько особенностей методов jQuery, которые не подробно описаны или даже не упомянуты в документации. Существуют также функции, доступные для объекта jQuery, не указанные в документации. Одним из подходов может быть просмотр источника jQuery github.com/jquery/jquery для сравнения с описаниями на документация. Вы также можете попытаться задать вопросы в IRC/чате irc.jquery.org и на форумах forum.jquery.com   -  person guest271314    schedule 05.04.2016
comment
@guest271314: До тех пор, пока версия 3.0 не будет действительно выпущена, вы можете предположить, что вопросы с jquery не используются (и документы jQuery не чтобы покрыть его). И даже тогда нам может понадобиться новый тег, учитывая, что они ведут себя совершенно по-разному.   -  person Bergi    schedule 05.04.2016
comment
@Bergi Да, документация, безусловно, не является исчерпывающей и не включает все варианты возможных параметров метода или функции; ни все доступные методы или функции jQuery. Например, .html(). Хотя в настоящее время Вопрос, по крайней мере, с точки зрения здесь, OP, похоже, пропустил вторую часть предложения из исходного Вопроса, где дается описание, которое пытается объяснить, что любое значение, переданное $.when() в качестве параметра, рассматривается как разрешенное jQuery.Deferred(). Это доступно в $.when() в версиях jQuery до 3.0.   -  person guest271314    schedule 05.04.2016
comment
@Bergi Пока 3.0 не будет действительно выпущен, вы можете предположить, что вопросы с тегами jquery не используют его (и документы jQuery не охватывают его). И даже в этом случае нам может понадобиться новый тег, учитывая, что они ведут себя совершенно по-разному. Добавить тег jquery-latest ? Включить "https://code.jquery.com/jquery-git.js" во фрагменты стека?   -  person guest271314    schedule 05.04.2016
comment
@Bergi meta.stackoverflow.com/questions/320491/   -  person guest271314    schedule 06.04.2016


Ответы (2)


Что документация пытается передать, так это то, что $.when() примет значение, которое не является ни jQuery.Deferred(), ни jQuery.promise(), ни Promise; значение будет рассматриваться как разрешенное jQuery.Deferred(), которое описано в следующей части предложения.

Если в jQuery.when() передается один аргумент, и он не является Deferred или Promise, он будет рассматриваться как разрешенный Deferred, и любые присоединенные doneCallbacks будут выполняться немедленно.

Например

$.when(1).then(function(data) {
  alert(data)
})
<script src="https://code.jquery.com/jquery-git.js">
</script>

person guest271314    schedule 05.04.2016
comment
Я спрашиваю, может ли $.when принимать объекты, подобные обещаниям. Документ говорит, что он принимает только Deferreds. Но в моем тестировании он принимает объекты, подобные обещаниям (т. е. Deferred.promise()). - person Jonathan Aquino; 07.04.2016
comment
@JonathanAquino В документе говорится, что он принимает только Deferreds. Где в документации это указано? $.when() принимает в качестве параметра любую переменную или объект; не только jQuery.Deferred(). Что вы подразумеваете под объектами, подобными обещаниям? Чего вы пытаетесь достичь, используя $.when()? - person guest271314; 07.04.2016
comment
@JonathanAquino Если в jQuery.when() передается один аргумент, и он не является Deferred или Promise, он будет рассматриваться как разрешенный Deferred, и любые подключенные doneCallbacks будут выполняться немедленно. jQuery.when() документация - person guest271314; 07.04.2016
comment
В нем указано, что он принимает Deferred'ы только вверху api.jquery.com/jquery.when - jQuery.when(отложено) - person Jonathan Aquino; 09.04.2016
comment
Я хочу сказать, что when() обрабатывает Deferred и Promises иначе, чем другие объекты. В верхней части документа должно быть указано jQuery.when(promises), а не jQuery.when(deferreds), потому что promises более общий, чем deferreds. - person Jonathan Aquino; 09.04.2016
comment
@JonathanAquino В нем указано, что он принимает Deferreds только в верхней части api.jquery.com/jquery.when. Это слово не отображается только в api.jquery.com/jquery.when? - person guest271314; 09.04.2016
comment
Хорошо, точка принята. Но моя точка зрения остается в силе: здесь должно быть написано jQuery.when(promises), а не jQuery.when(deferreds). - person Jonathan Aquino; 09.04.2016
comment
Потому что, если вы ищете способ объединить несколько обещаний в одно, то $.when — это то, что вам нужно. - person Jonathan Aquino; 09.04.2016
comment
@JonathanAquino Я хочу сказать, что when() обрабатывает Deferred и Promises иначе, чем другие объекты. Каким образом? $.when() преобразует параметр в разрешенный объект-обещание jQuery, если параметр не является обещанием или отложенным объектом. Но моя точка зрения остается в силе: здесь должно быть написано jQuery.when(обещания), а не jQuery.when(отложенные).? Не уследил, вот. Что ты имеешь в виду? Вы должны иметь возможность использовать $.when() с несколькими отложенными объектами в качестве параметра. - person guest271314; 09.04.2016
comment
Отложенные реализуют интерфейс обещания. $.when может обрабатывать как промисы, так и отложенные. Поэтому он должен просто сказать $.when(обещания), потому что он может обрабатывать оба. - person Jonathan Aquino; 09.04.2016
comment
Здесь я говорю об обещаниях jquery (jQuery 2), а не о реальных обещаниях Promise/A. - person Jonathan Aquino; 09.04.2016
comment
@JonathanAquino Deferreds реализуют интерфейс обещания. , Таким образом, он должен просто сказать $.when(promises), потому что он может обрабатывать оба. , Я говорю о jquery обещания здесь (jQuery 2), а не настоящие обещания/обязательства. Не уверены, что вы пытаетесь передать? Можете ли вы создать jsfiddle jsfiddle.net, чтобы продемонстрировать различия между jQuery.Deferred() и jQuery.fn.promise() ? И чем ожидаемый результат или фактический результат отличается от описанного в документации? - person guest271314; 09.04.2016
comment
Увы, я сдаюсь :( - person Jonathan Aquino; 09.04.2016
comment
Давайте продолжим обсуждение в чате. - person guest271314; 09.04.2016

Я думаю, вы могли бы сказать, что Deferred — это Promise, но Promise — это не Deferred.

На самом деле это совершенно разные интерфейсы, только jQuery, смешанный с промисным API в их отложенных. См. В чем разница между Deferred, Promise и Future в JavaScript?

Может ли $.when() принимать обещания или отсрочки?

Да, это может занять и то, и другое. Но обратите внимание: когда вы уже знаете, что у вас есть обещание или отложенное выполнение, нет смысла вызывать для него $.when.

Есть ли ошибка в документе?

Да, видимо. И дело даже не в том, что он обрабатывает только отложенные и промисы как асинхронные значения — скорее, он выполняет какую-то проверку утиного ввода. Вы захотите ознакомиться с фактической реализацией. :

if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) )

Затем он вызывает метод promise (или другой promise метод или действительно любой .promise метод) для значения и ожидает, что возвращаемый объект будет иметь соответствующие цепные методы для добавления слушателей.

person Bergi    schedule 05.04.2016
comment
Похоже, что эта часть документации на самом деле описывает $.when() принятие любого параметра - не только jQuery.Deferred() объекта jQuery .promise() или родного Promise ; и рассматривая этот параметр как разрешенный jQuery.Deferred(). OP пропустил остаток предложения в цитате исходного вопроса; таким образом, возможна путаница в отношении цитаты из документации и того, что она пытается передать, - и текущего вопроса. OP может пытаться спросить, в чем разница между объектом jQuery.Deferred() и jQuery .promise() - и, возможно, Promise; хотя это не ясно в вопросе. - person guest271314; 05.04.2016
comment
@guest271314: Конечно, всем понятно, что любые значения, не идентифицированные как обещанные, будут рассматриваться непосредственно как значения выполнения. Мой ответ только разъясняет, что можно обетовать, а что нет. - person Bergi; 05.04.2016
comment
Не могли бы вы расширить Но обратите внимание, что если вы уже знаете, что у вас есть промис или отсрочка, нет смысла вызывать $.when для него.? Я все еще не совсем понимаю Promise и Deferred, и я думаю, что небольшое объяснение, почему (нет смысла), поможет и мне, и будущим посетителям. - person Stephen P; 06.04.2016
comment
@StephenP: Я имею в виду, что вместо того, чтобы делать $.when($.ajax(…)).then(…) (как в ужасном примере в документации), вы должны просто сделать $.ajax(…).then(…). $.when хорош только тогда, когда у вас есть значения, предоставленные пользователем (вызывающим вашу функцию), и вы не знаете, являются ли они обещанием или простым значением: $.when(couldBeAnything).then(function(nowSurelyIsPlainValue) {…}) - person Bergi; 06.04.2016
comment
@Bergi Вы сказали. Но обратите внимание, что, когда вы уже знаете, что у вас есть обещание или отсрочка, нет смысла вызывать $.when для него. Я подумал, что $.when объединит несколько промисов — разве это не веская причина для его использования? - person Jonathan Aquino; 07.04.2016
comment
@JonathanAquino: Да, это хорошая причина для его использования - проблема с jQuery.when в том, что это ужасная смесь между Promise.resolve и Promise.all - person Bergi; 07.04.2016