Can I get a jQuery Deferred on document.ready()?

2019-01-22 12:50发布

Right after my script is loaded I am making an Ajax request to get some translations. This should always return after the document is ready since I am loading my scripts at the bottom of the page, but I am still curious if it would be possible to get a Deferred Object on the document ready state.

That way it would be possible to make sure that both, the document is ready and the Ajax call returned successfully before doing anything else, e.g. like this:

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

6条回答
仙女界的扛把子
2楼-- · 2019-01-22 13:31

You can associate a deferred object with the document using data(), and resolve() it in your ready handler. This way, you should be able to use the stored deferred object with $.when():

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

$.when($.ajax("translations"), $(document).data("readyDeferred"))
 .then(function() {
    // Start doing stuff here.
});
查看更多
我命由我不由天
3楼-- · 2019-01-22 13:32

My version is:

$.when(
  $.Deferred(function() { $(this.resolve); }), 
  $.ajax('translations')).
  then(function() { console.log("done"); });
查看更多
爱情/是我丢掉的垃圾
4楼-- · 2019-01-22 13:32

jQuery's when is not a proper promise. You can force it into one like this:

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

Usage:

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

It happens to resolve with $ so that's kind of convenient too.

Alternative implementation:

function documentReady() {
    return new Promise(r => $(r));
}
查看更多
小情绪 Triste *
5楼-- · 2019-01-22 13:33

Update for reference (2015):

This is available in current versions of jQuery:

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

It is also simple to convert to a stream using highlandjs:

_($.when($.ready)).map(transform).pipe(output) // etc.
查看更多
不美不萌又怎样
6楼-- · 2019-01-22 13:36

Here's a cleaned up version of ircmaxell's comment:

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

edit

Some clarification to stop the incorrect edits:

Passing a function to the jquery object (e.g. $(some_func)) is the same as $(document).ready(some_func).

Therefore, the $(doc_ready.resolve); line is just shorthand for something like this:

$(document).ready(function() {
  doc_ready.resolve()
});
查看更多
放我归山
7楼-- · 2019-01-22 13:46

Try this:

$.when($.ajax('translations'), $.ready).then(function() {
    // Start doing stuff here
});
查看更多
登录 后发表回答