Могу ли я получить отложенный jQuery в document.ready ()?

#jquery #ajax #jquery-deferred

#jquery #ajax #jquery-отложенный

Вопрос:

Сразу после загрузки моего скрипта я делаю Ajax-запрос, чтобы получить некоторые переводы. Это всегда должно возвращаться после того, как документ готов, поскольку я загружаю свои скрипты внизу страницы, но мне все еще интересно, можно ли получить отложенный объект в состоянии готовности документа.

Таким образом, можно было бы убедиться, что и документ готов, и вызов Ajax успешно возвращен, прежде чем делать что-либо еще, например, вот так:

 $.when( $.ajax('translations'), document.ready())
.then(function(){
    // Start doing stuff here
});
  

Ответ №1:

Вы можете связать отложенный объект с документом, используя data(), и разрешить () его в вашем ready обработчике. Таким образом, вы сможете использовать сохраненный отложенный объект с помощью $.when():

 $(document).data("readyDeferred", $.Deferred()).ready(function() {
    $(document).data("readyDeferred").resolve();
});

$.when($.ajax("translations"), $(document).data("readyDeferred"))
 .then(function() {
    // Start doing stuff here.
});
  

Комментарии:

1. Спасибо, просто и понятный. Вероятно, это также будет работать с глобальной переменной или чем-то подобным.

2. @Daff, безусловно. Я лично предпочитаю использовать data() вместо глобальной переменной, потому что это более гибко и позволяет избежать загрязнения глобального пространства имен.

3. Педантичное замечание. Вообще нет причин сохранять переменную. Это нужно только на этапе настройки, поэтому используйте область закрытия: (function() { var deferred = new $.Deferred(); $(function() { deferred.resolve(); }); $.when($.ajax('foo'), deferred).then(function() {}); })(); … Если вы используете локальные области, нет необходимости сохранять, просто позвольте замыканиям привязать его к вам…

Ответ №2:

Вот очищенная версия комментария ircmaxell:

 (function() {
  var doc_ready = $.Deferred();
  $(doc_ready.resolve);
  $.when(doc_ready, $.ajax('translations')).then(function() {
    console.log("done");
  });
})();
  

Редактировать

Некоторые пояснения, чтобы остановить неправильные изменения:

Передача функции объекту jquery (например, $(some_func) ) выполняется так же, как $(document).ready(some_func) .

Следовательно, $(doc_ready.resolve); строка является просто сокращением для чего-то вроде этого:

 $(document).ready(function() {
  doc_ready.resolve()
});
  

Ответ №3:

Попробуйте это:

 $.when($.ajax('translations'), $.ready).then(function() {
    // Start doing stuff here
});
  

Комментарии:

1. Обратите внимание, что на самом деле это не отложенный, но в любом случае у $.ready него есть promise метод.

2. Нет, это еще не задокументировано: github.com/jquery/api.jquery.com/issues/205

Ответ №4:

Моя версия:

 $.when(
  $.Deferred(function() { $(this.resolve); }), 
  $.ajax('translations')).
  then(function() { console.log("done"); });
  

Комментарии:

1. Мне нравится, как содержится отложенный. Одним из предложений было бы изменить порядок ваших отложенных запросов, чтобы первым аргументом вашей функции обратного вызова было любое значение, которое было разрешено для отложенного $.ajax.

Ответ №5:

Обновление для справки (2015):

Это доступно в текущих версиях jQuery:

 $.when($.ready).then(...);
  

Также просто преобразовать в поток, используя highlandjs:

 _($.when($.ready)).map(transform).pipe(output) // etc.
  

Комментарии:

1. Как упоминалось ранее, не задокументировано, что $.ready является отложенным подобным объектом. В 2016 году это все еще недокументировано.

2. В этой ссылке есть кое-что об этом: api.jquery.com/jQuery.ready/#jQuery-ready1

3. Да, это было добавлено в документацию по состоянию на март 2017 года

Ответ №6:

jQuery when не является надлежащим обещанием. Вы можете принудительно преобразовать его в такой:

 function documentReady() {
    return Promise.resolve($.when($.ready));
}
  

Использование:

 documentReady().then(function($) { ... });
  

Случается, что это разрешается с помощью $ , так что это тоже вроде как удобно.

Альтернативная реализация:

 function documentReady() {
    return new Promise(r => $(r));
}