前の 2 つの記事では、JS ファイルまたは JS モジュールを動的にロードして段階的に実装する方法を紹介しました。
まず、モジュールのロードとコールバック関数の分離が同期戦略によって実現され、次にモジュールのロードとコールバック関数の分離が非同期戦略によって実現されます。
この記事は主に、非同期戦略を最適化し、ランダムな読み込み (モジュールを任意の順序で読み込むのではなく) を実現する方法について説明します。ページの準備完了後にファイルが読み込まれます。前回の記事で残った質問を取り上げましょう
1. 準備ができたらページをロードします
2. モジュールを任意に追加してロードします
最初を見てください質問、この質問は、主にページの DOMContentLoaded イベントをリッスンするもので、ここでは説明しません。インターネットで検索するとたくさんの答えが見つかったので、コードを直接参照しました。 。
Using.ready = function(callback){
readyList.push(callback);
if(document.addEventListener){
document.addEventListener("DOMContentLoaded",_ready,false);
>// IE の場合
var domReady = function(){
try{
document.documentElement.doScroll("left");
_ready();
setTimeout(domReady,1);
return;
}
}
domReady()
}
このコードはおそらく
コードをコピー
コードは次のとおりです: document.documentElement .doScroll("left");
これは、簡単に言えば、IE のラベルが読み込まれた後、この原理を使用して判断できます。 IE のページが読み込まれたかどうか。
この関数には _ready 関数があり、ページがロードされた後にすべてのロード関数を実行するために使用されます。コード
を貼り付けます (この段落を編集: ページがロードされた後の Ready 関数は、私たちが考えるネイティブ JS の window.load ではありません。簡単に言うと、これは単に DOM 構造を詳細な情報については、Baidu で Google で確認できます)
var _ready = function(){
while(readyList.length > 0){
var func = readyList.shift(); );
}
document.removeEventListener("DOMContentLoaded",_ready,false);
このブログ投稿の焦点は次のとおりです。まずコードを見てみましょう
コードをコピーします
_execAsyn()
}
まだ通知を使用しています 必要なモジュールがロードされていますが、それに asynQueue 配列と _execAsyn 関数が追加されています。それらの関数はそれぞれ
asynQueue は、非同期ロード後にコールバックされる関数を保存するために使用されます。説明する必要はありません。
_execAsyn は、保存されたコールバック関数を実行するために使用される配列です。つまり、保存された関数を 1 つずつ実行します。コードを見てください。コード内の各行の機能はコメント化されています。
コードをコピーします。
コードは次のとおりです。
// _execAsyn 関数を実行状態に変更します。
_execAsyn.isRunning = true;実行する必要があるキュー内の最初の関数
func = asynQueue.shift();
// 非同期読み込みモジュールの using.fn.script 関数を呼び出し、読み込み後に実行する必要があるコールバック関数を渡します完了しました
Using.fn.script(function(){
// 実行する必要がある現在の関数
func();
// 実行する必要のある関数がなくなるまで _execAsyn を繰り返します
_execAsyn();
});
/ / キュー内に実行する必要がある関数がない場合
}else{
// _execAsyn を変更します実行ステータスを false にします
_execAsyn.isRunning = false;
}
}
This function is nothing special to explain. To put it bluntly, it just executes the functions that need to be executed one by one. Then, the only thing that needs attention is why loops are not used when operating the queue, but iteration is used. The reason is
1. There may be new functions that need to be executed at any time in the queue. If a loop is used, the latest function may not be executed because the function is always inserted at the end of the queue
2 . Using.fn.script is asynchronous. If it is a loop, the current function has not been executed yet, and the next function may have entered the execution state. So, in itself, the speed of executing several functions at the same time may be higher. Why do we need to limit the parallelism of multiple functions here? The reason is also very simple, because every time a function in the queue is executed, the corresponding module may need to be loaded. So if two or more functions that rely on the same module need to be executed and are executed in parallel, the same module may be loaded. Multiple times, and may cause subsequent functions to fail to execute and cause exceptions.
This is the core part of the entire UsingJS. In it, I added the Using.Class.create function, which is mentioned at the end of the javascript dynamic loading article.
Finally take a look at the page usage:
This piece of code is deliberately loaded repeatedly, and the Using package is carried out after multiple Ready events and Ready.
There is one thing that needs special attention
Using("Http");
Using.asyn(function(){
var http = new Using.Modules.Http();
http.set("xxx");
http .show();
});
// If you use
// var ht = new Using.Modules.Http();
// Using.Modules will be reported. Http is not a constructor
// The reason is that
// Any operation is asynchronous. When this sentence is executed, the module loading of Using("Http") may not be completed yet
// This is The mistake Zhongmou makes when using it for multiple friends is always thinking that everything will be fine after importing the package
// Yes, it should be like this. After importing the package, you can cite it anywhere
// But there must be a prerequisite That means the module has to be loaded
// So please write all the code in Using.asyn
Using.asyn(function(){
var h = new Using.Modules.Http ();
h.set("ooo");
h.show();
});
UsingJS Download