Download jQuery using JavaScript using Promises

The previous question showed how to load jQuery using embedded JavaScript. I successfully used the callback code from the answer there, replicated here:

// Anonymous "self-invoking" function (function() { // Load the script var script = document.createElement("SCRIPT"); script.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'; script.type = 'text/javascript'; document.getElementsByTagName("head")[0].appendChild(script); // Poll for jQuery to come into existance var checkReady = function(callback) { if (window.jQuery) { callback(jQuery); } else { window.setTimeout(function() { checkReady(callback); }, 100); } }; // Start polling... checkReady(function($) { // Use $ here... }); })(); 

How can I accomplish the same thing using native JavaScript Promises?

The reason I'm asking is because I suddenly need to disconnect from the previous callback, and this is an unpleasant mess. I hope Promises is the best way and I have no real interest in using the loader framework.

Here is what I have so far, but the promise always ends rejected:

 // This code doesn't work quite right. // Poll for jQuery to come into existance using a Promise var jQueryReady = new Promise( function(resolve, reject) { // Load jQuery var script = document.createElement('SCRIPT'); script.type = 'text/javascript'; script.src = 'https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js'; document.getElementsByTagName('head')[0].appendChild(script); if (window.jQuery) { resolve("YAY"); } else { reject("UGH"); } }); jQueryReady.then( function(success) { console.log(success); }, function(error) { console.error("Really helpful error:", error); }); 

(I apologize for my complete ignorance.)

+5
source share
3 answers

Here's the version that makes a simple loadScript() function that returns a promise and then provides a wrapper around it that detects that jQuery is already loaded:

 function loadScript(url) { return new Promise(function(resolve reject) { var script = document.createElement("script"); script.onload = resolve; script.onerror = reject; script.src = url; document.getElementsByTagName("head")[0].appendChild(script); }); } function loadjQuery() { if (window.jQuery) { // already loaded and ready to go return Promise.resolve(); } else { return loadScript('https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js'); } } // Usage: loadjQuery().then(function() { // code here that uses jQuery }, function() { // error loading jQuery }); 

Notes on your code:

  • In your first block of code, setting one timer and assuming the script will load when this timer fires, it looks like roulette. This may work most of the time, but it is not a purely reliable way of doing something. In addition, to be safe, you must set the timer for a longer period of time than is usually necessary. Instead, you should run onload based on the script callback. Then you will know exactly when the script is ready with 100% reliability.

  • In your second code block, the version of your promise successfully handles the case when jQuery is already loaded, but then rejects() when jQuery needs to be customized. As you can see from my example, you need resolve() when the loaded script tag has finished loading so that your promise works as desired.

+5
source

Scripts inserted on the page in this way are executed asynchronously. (See “Dynamically import scripts” in MDN.) As a result, window.jQuery will always be undefined .

Try attaching the onload handler to the script element so that Promise permission is only executed after the script is executed.

For example (before installing script.src ):

 script.onload = function () { if (window.jQuery) { resolve("YAY"); } else { reject("UGH"); } }; 

As usual, this method is not compatible with all browsers. Check this post for ways to post them.

0
source

The problem is that it is an asynchronous non-blocking way to load javascript. You will need to wait for the browser script to load.

This is a possible solution:

 var jQueryReady = new Promise( function(resolve, reject) { // Load jQuery var script = document.createElement('SCRIPT'); script.type = 'text/javascript'; script.src = 'https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js'; document.getElementsByTagName('head')[0].appendChild(script); // You should also have a timeout in case your script never loads var timeoutHandler = setTimeout(10000, function() { if (checkIntervalHandler) clearInterval(checkIntervalHandler); reject("UGH"); }); var checkIntervalHandler = setInterval(500, function() { if (window.jQuery) { if(timeoutHandler) clearTimeout(timeoutHandler); resolve("YAY"); } }); }); 
0
source

Source: https://habr.com/ru/post/1240013/


All Articles