การโหลดโมดูลจะแบ่ง JS ออกเป็นหลายโมดูลเพื่อการพัฒนาและการบำรุงรักษาที่ง่าย ดังนั้นเมื่อโหลดโมดูล JS จำนวนมากจำเป็นต้องโหลดแบบไดนามิกเพื่อปรับปรุงประสบการณ์ผู้ใช้
ก่อนที่จะแนะนำไลบรารีการโหลดโมดูลเราจะแนะนำวิธีการ
การโหลดแบบไดนามิกของวิธี JS:
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น loadjs (url, callback) {
var node = document.createElement ("สคริปต์");
โหนด [window.addeventListener? "OnLoad": "OnReadyStateChange"] = function () {
if (window.addeventListener || /loadedEd THECHETETETENTET /I.TEST(NODE.READYSTATE)) {
การโทรกลับ ();
node.onreadyStateChange = null;
-
-
node.onerror = function () {};
node.src = url;
var head = document.getElementsByTagname ("head") [0];
head.insertbefore (node, head.firstchild); // ก่อนที่จะแทรกลงในโหนดแรกของศีรษะป้องกันไม่ให้แท็กหัวภายใต้ IE6 จากการถูกปิดและใช้ AppendChild เพื่อรายงานข้อผิดพลาด
-
เนื่องจาก Situ Zhengmei ใช้กรอบมวลที่เขียนเพื่อแนะนำการโหลดโมดูลที่ใช้มากที่สุดในอุตสาหกรรมนั้นจำเป็นต้องใช้ JS และ SEA.JS. ดังนั้นฉันคิดว่าเขามีบุคลิกที่แข็งแกร่ง
ให้ฉันพูดถึงกระบวนการโหลดของทะเล js:
หน้า chaosan.js ได้รับการแนะนำในแท็กหัวและวัตถุ SEAJS จะได้รับ
ยังแนะนำ index.js
รหัสของ index.js มีดังนี้:
การคัดลอกรหัสมีดังนี้:
sejs.use (['./ a', 'jQuery'], ฟังก์ชั่น (a, $) {
var num = aa;
$ ('#j_a') ข้อความ (num);
-
A.JS:
การคัดลอกรหัสมีดังนี้:
กำหนด (ฟังก์ชั่น (ต้องการ, การส่งออก, โมดูล) {
var b = ต้องการ ('./ b');
var a = function () {
ส่งคืน 1 + parseint (bb ());
-
Exports.a = A;
-
B.JS:
การคัดลอกรหัสมีดังนี้:
กำหนด (ฟังก์ชั่น (ต้องการ, การส่งออก, โมดูล) {
var c = ต้องการ ('./ c');
var b = function () {
ส่งคืน 2 + parseint (cc ());
-
การส่งออก b = b;
-
C.JS:
การคัดลอกรหัสมีดังนี้:
กำหนด (ฟังก์ชั่น (ต้องการ, การส่งออก, โมดูล) {
var c = function () {
กลับ 3;
-
การส่งออก c = c;
-
จากข้างต้นเราจะเห็นว่าโมดูล A ขึ้นอยู่กับ B และ B ขึ้นอยู่กับ C
เมื่อโปรแกรมเข้าสู่ index.js SEAJS จะเรียกวิธีการใช้งาน
การคัดลอกรหัสมีดังนี้:
seajs.use = function (ids, callback) {
GlobalModule._USE (IDS, CallBack)
-
คำอธิบาย: เมื่อ GlobalModule เริ่มต้นใน SEAJS (เมื่อมีการแนะนำ sea.js) อินสแตนซ์ของโมดูล var globalmodule = โมดูลใหม่ (util.pageuri, status.compiled)
ในเวลานี้ ids -> ['./a' ,'jQuery'], callback -> function (a, $) {var num = aa; $ ('#j_a') ข้อความ (num);}
ถัดไป globalModule._USE (รหัสการโทรกลับ) จะถูกเรียก
การคัดลอกรหัสมีดังนี้:
module.prototype._use = function (ids, callback) {
var uris = resolve (ids, this.uri); // ความละเอียด ['./a' ,'jquery']
this._load (uris, function () {// เรียกที่อยู่ของโมดูลที่แยกวิเคราะห์และ jQuery [url1, url2] และเรียกใช้วิธี _load
//util.map: ให้สมาชิกข้อมูลทั้งหมดดำเนินการฟังก์ชั่นที่ระบุในแต่ละครั้งและส่งคืนอาร์เรย์ใหม่ซึ่งเป็นผลมาจากการเรียกใช้การเรียกกลับของสมาชิกอาร์เรย์ดั้งเดิม
var args = util.map (uris, function (uri) {
กลับ uri? CachedModules [uri] ._ compile (): null; // ถ้า url มีอยู่ให้เรียกวิธี _compile
-
if (callback) {callback.apply (null, args)}
-
-
เนื่องจากหลังจากเรียกเมธอด _load ฟังก์ชั่นการโทรกลับสองฟังก์
ตั้งค่า this._load (uris, function () {}) วิธีการโทรกลับวิธีการเรียกกลับไปที่การเรียกกลับ 2
วิธีการแก้ไขคือการแก้ไขที่อยู่โมดูลดังนั้นฉันจะไม่เข้าไปดูรายละเอียดที่นี่
ในที่สุด URIS ใน var uris = Resolve (ids, this.uri) ถูกแยกวิเคราะห์เป็น ['http: //localhost/test/seajs/a.js' ,'http: //localhost/test/seajs/lib/juqery/1.7.2/juqery
และถัดไปสิ่งนี้จะถูกดำเนินการ
การคัดลอกรหัสมีดังนี้:
// เมธอด _load () จะพิจารณาว่าไฟล์ทรัพยากรใดยังไม่พร้อม หากไฟล์ทรัพยากรทั้งหมดอยู่ในสถานะพร้อมการเรียกกลับ 2 จะถูกเรียกใช้งาน
// ในกรณีนี้เราจะทำการพึ่งพาเป็นวงกลมและทำการโหลดบน JS ที่ไม่ได้โหลด
module.prototype._load = function (uris, callback2) {
//util.filter: ให้สมาชิกข้อมูลทั้งหมดดำเนินการฟังก์ชั่นที่ระบุในแต่ละครั้งและส่งคืนอาร์เรย์ใหม่ อาร์เรย์เป็นสมาชิกที่ส่งคืนจริงหลังจากดำเนินการโทรกลับจากสมาชิกอาร์เรย์ดั้งเดิม
// unloadeduris เป็นอาร์เรย์ของโมดูลที่ไม่ได้รวบรวม
var unloadeduris = util.filter (uris, function (uri) {
// ส่งคืนสมาชิกที่มีค่าฟังก์ชั่นการดำเนินการบูลีนเป็นจริงส่งคืนจริงเมื่อมี URI อยู่และไม่มีอยู่ใน cachemodules ตัวแปรภายในหรือเก็บค่าสถานะของสถานะน้อยกว่าสถานะพร้อมในข้อมูลการจัดเก็บข้อมูล
// ถ้าสถานะ. ค่าพร้อมคือ 4 ถ้าน้อยกว่าสี่จะเป็นไปได้ที่จะถูกเรียกคืนและดาวน์โหลด
กลับ uri && (! cachedmodules [uri] ||
cachedmodules [uri] .status <status.ready)
-
// หากโมดูลทั้งหมดใน URIS พร้อมให้เรียกใช้การโทรกลับและออกจากร่างกายฟังก์ชั่น (คราวนี้วิธี _compile ของโมดูลจะถูกเรียก)
var length = unloadeduris.length
if (length === 0) {callback2 () return}
// จำนวนโมดูลที่ไม่ได้โหลด
var retire = ความยาว
// สร้างการปิดและพยายามโหลดโมดูลที่ไม่ได้โหลด
สำหรับ (var i = 0; i <length; i ++) {
(ฟังก์ชั่น (uri) {
// ตัดสินว่าข้อมูลการจัดเก็บ URI ไม่มีอยู่ในตัวแปรภายใน cachedModules หรือไม่
var module = cachedModules [uri] ||
(CachedModules [uri] = โมดูลใหม่ (URI, status.fetching))
// หากค่าสถานะของโมดูลมากกว่าหรือเท่ากับ 2 หมายความว่าโมดูลได้รับการดาวน์โหลดและมีอยู่แล้ว ในเวลานี้มีการดำเนินการ onfetched ()
// มิฉะนั้น fetch (uri, onfetched) ถูกเรียกให้พยายามดาวน์โหลดไฟล์ทรัพยากร ONLOAD จะถูกเรียกใช้หลังจากดาวน์โหลดไฟล์ทรัพยากรและวิธีการ onfetched จะถูกดำเนินการใน ONLOAD
module.status> = status.fetched? onfetched (): fetch (uri, onfetched)
ฟังก์ชั่น onfetched () {
โมดูล = cachedModules [uri]
// เมื่อค่าสถานะของโมดูลมีค่ามากกว่าหรือเท่ากับสถานะการประหยัดหมายความว่าได้รับข้อมูลการพึ่งพาทั้งหมดของโมดูล
if (module.status> = status.saved) {
// getpuredence -insependencies: รับอาร์เรย์การพึ่งพาโดยไม่มีการพึ่งพาเป็นวงกลม
var deps = getpuredencies (โมดูล)
// หากอาร์เรย์การพึ่งพาไม่ว่างเปล่า
ถ้า (deps.length) {
// ดำเนินการเมธอด _load () อีกครั้งจนกว่าการพึ่งพาทั้งหมดจะถูกโหลดและการโทรกลับจะดำเนินการหลังจากการโหลดของการพึ่งพาทั้งหมดเสร็จสิ้น
module.prototype._load (deps, function () {
CB (โมดูล)
-
-
// หากอาร์เรย์การพึ่งพาว่างเปล่าให้ดำเนินการ CB (โมดูล) โดยตรง
อื่น {
CB (โมดูล)
-
-
// หากการได้มาล้มเหลวเช่น 404 หรือไม่สอดคล้องกับข้อกำหนดแบบแยกส่วน
// ในกรณีนี้ module.status จะได้รับการบำรุงรักษาที่การดึงหรือดึงข้อมูล
อื่น {
CB ()
-
-
}) (unloadeduris [i])
-
// CB Method - เรียกใช้การโทรกลับหลังจากโหลดโมดูลทั้งหมด
ฟังก์ชั่น CB (โมดูล) {
// หากข้อมูลการจัดเก็บของโมดูลมีอยู่ให้แก้ไขค่าสถานะในข้อมูลการจัดเก็บโมดูลและแก้ไขเป็นสถานะพร้อม
โมดูล && (module.status = status.ready)
// การเรียกกลับจะดำเนินการเฉพาะเมื่อโหลดโมดูลทั้งหมด
-remain === 0 && callback2 ()
-
-
-
ที่นี่ความยาวอาร์เรย์ของ unloadeduris คือ 2, ['http: //localhost/test/seajs/a.js' ,'http: //localhost/test/seajs/lib/juqery/1.7.2/juqery-debug.js'
ใช้ http: //localhost/test/seajs/a.js เป็นตัวอย่าง
ถัดไป: ก่อนอื่นโมดูลจะถูกสร้างขึ้น:
การคัดลอกรหัสมีดังนี้:
CachedModules ('http: //localhost/test/seajs/a.js') = โมดูลใหม่ ('http: //localhost/test/seajs/a.js',1)
module.status> = status.fetched? onfetched (): fetch (uri, onfetched)
เนื่องจากโมดูล A ไม่ได้โหลดในเวลานี้ Fetch (URI, onfetched) จะถูกดำเนินการต่อไปนั่นคือ Fetch ('http: //localhost/test/seajs/a.js'getched)
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่นดึงข้อมูล (uri, onfetched) {
// แทนที่ URI ด้วยที่อยู่คำขอใหม่ตามกฎในแผนที่
var requesturi = util.parsemap (uri)
// ก่อนอื่นดูว่ามีการบันทึกการร้องขออยู่ในรายการที่ได้รับ
if (fetchedList [requesturi]) {
// ในเวลานี้รีเฟรชข้อมูลการจัดเก็บโมดูลของ URI ดั้งเดิมไปยัง Requesturi ที่กำหนดใหม่โดย MAP
cachedmodules [uri] = cachedmodules [requesturi]
// ดำเนินการ onfetched และ return ซึ่งหมายความว่าได้รับโมดูลสำเร็จ
onfetched ()
กลับ
-
// ข้อมูลการจัดเก็บข้อมูลของ Query Requesturi ในรายการรับ
ถ้า (fetchingList [requesturi]) {
// เพิ่มการโทรกลับที่สอดคล้องกับ URI ในรายการโทรกลับและส่งคืน
รายการโทรกลับ [requesturi] .push (onfetched) // หากถูกเรียกคืนให้กดวิธีการโทรกลับแบบ onfetched ของโมดูลนี้ลงในอาร์เรย์และส่งคืน
กลับ
-
// หากโมดูลที่คุณพยายามรับจะไม่ปรากฏใน FetchEdList และ FetchingList ให้เพิ่มข้อมูลในรายการคำขอและรายการโทรกลับตามลำดับตามลำดับ
FetchingList [requesturi] = true
รายการโทรกลับ [requesturi] = [onfetched]
// ดึงมา
module._fetch (
ขอ
การทำงาน() {
FetchedList [requesturi] = true
// อัปเดตสถานะโมดูล
// ถ้า module.status เท่ากับ status.fectching แก้ไขสถานะโมดูลเป็นดึงข้อมูล
var module = cachedModules [uri]
if (module.status === status.fetching) {
module.status = status.fetched
-
ถ้า (fetchingList [requesturi]) {
ลบ FetchingList [Requesturi]
-
// การโทรกลับการเรียกใช้การเรียกกลับแบบ Unified Unified
if (callbackList [requesturi]) {
util.foreach (callbacklist [requesturi], function (fn) {
fn () // fn เป็นวิธี onfeched ที่สอดคล้องกับโมดูล
-
ลบรายการโทรกลับ [Requesturi]
-
-
config.charset
-
-
ถัดไป module._fetch () จะถูกดำเนินการและเราเรียกฟังก์ชันการโทรกลับที่นี่เป็น callback3
วิธีนี้คือการเรียกใช้วิธีการโหลด JS เพื่อดาวน์โหลดไฟล์ A.JS แบบไดนามิก (เนื่องจากมีและ jQuery จะมีการสร้างสคริปต์ใหม่สองรายการ) มีคำถามที่นี่ หากคุณสร้างสคริปต์สำหรับ A และเพิ่มลงในหัวคุณจะดาวน์โหลดไฟล์ JS อย่างไรก็ตามใน SEAJS จะไม่ดาวน์โหลด แต่คุณจะรอจนกว่าสคริปต์สำหรับ jQuery จะถูกสร้างและเพิ่มลงในหัวก่อนที่คุณจะดาวน์โหลด (Google Debugger ตั้งค่าเบรกพอยต์ นี่คือเหมา?
(แนะนำที่นี่: http://ux.sohu.com/topics/50972D9AE7DE3E752E0081FF ฉันจะพูดถึงคำถามเพิ่มเติมที่นี่คุณอาจรู้ว่าทำไมเราต้องใช้ตารางเล็ก ๆ น้อย ๆ ก่อนที่มันจะปรากฏขึ้นและ DIV จะแสดงให้เห็นมากที่สุดเท่าที่จะแยกวิเคราะห์ได้
หลังจากการดาวน์โหลดสำเร็จจะมีการแยกวิเคราะห์และดำเนินการและวิธีการกำหนดจะถูกดำเนินการ ที่นี่เราจะเรียกใช้รหัสของโมดูล
กำหนด (id, deps, function () {}) การวิเคราะห์วิธีการ
การคัดลอกรหัสมีดังนี้:
// กำหนดคำจำกัดความ, ID: โมดูล ID, deps: การพึ่งพาโมดูล, โรงงาน
module._define = function (id, deps, โรงงาน) {
// แก้ไขการพึ่งพา // ถ้า deps ไม่ใช่ประเภทอาร์เรย์โรงงานเป็นฟังก์ชัน
if (! util.isarray (deps) && util.isfunction (Factory)) {// ฟังก์ชั่นร่างกายตรงกับสตริงที่ต้องการและรูปแบบอาร์เรย์เพื่อส่งคืนการมอบหมายให้ deps
deps = util.parsedependencies (Factory.toString ())
-
// ตั้งค่าข้อมูลเมตา
var meta = {id: id, การพึ่งพา: deps, โรงงาน: โรงงาน}
if (document.attachevent) {
// รับโหนดของสคริปต์ปัจจุบัน
var script = util.getCurrentScript ()
// ถ้ามีโหนดสคริปต์อยู่
ถ้า (สคริปต์) {
// รับที่อยู่ URI ดั้งเดิม
deriveduri = util.unparSemap (util.getScriptabsolutesrc (สคริปต์))}
ถ้า (! deriveduri) {
util.log ('ล้มเหลวในการหา URI จากสคริปต์แบบโต้ตอบสำหรับ:', factory.toString (), 'เตือน')
-
-
-
-
กำหนดจะทำการตัดสินในโรงงานก่อนเพื่อพิจารณาว่าเป็นฟังก์ชัน (เหตุผลก็คือคำจำกัดความสามารถรวมไฟล์และวัตถุ)
หากเป็นฟังก์ชั่นฟังก์ชั่นจะได้รับผ่านโรงงาน Tostring () และการพึ่งพาของ A.JS นั้นถูกจับคู่เป็นประจำและการพึ่งพาจะถูกบันทึกไว้ใน DEPS
สำหรับ A.js การพึ่งพาของมันคือ b.js ดังนั้น deps คือ ['./b']
และบันทึกข้อมูลของ a.js var meta = {id: id, การพึ่งพา: deps, โรงงาน: โรงงาน}
สำหรับ a.js meta = {id: undefined, การพึ่งพา: ['./b'], โรงงาน: ฟังก์ชั่น (xxx) {xxx}}
ในเบราว์เซอร์ IE 6-9 คุณสามารถใช้เส้นทางไปสู่การเรียกใช้ JS อย่างไรก็ตามในเบราว์เซอร์มาตรฐานสิ่งนี้ไม่สามารถทำได้ดังนั้นคุณสามารถกำหนดข้อมูลเมตาให้กับ AnonymousModulemeta = Meta
จากนั้นทริกเกอร์ onload และวิธีการโทรกลับ 3 จะถูกเรียก วิธีการโทรกลับนี้จะแก้ไขค่าสถานะของโมดูลการโทรกลับปัจจุบัน (a.js) และตั้งค่าเป็น module.status = status.fetched
ถัดไปการโทรกลับที่สอดคล้องกับ a.js ในคิวการโทรกลับคิวจะถูกดำเนินการอย่างสม่ำเสมอนั่นคือ onfetched
วิธีการ onfetched ตรวจสอบว่าโมดูล A มีโมดูลขึ้นอยู่กับหรือไม่ เนื่องจาก A ขึ้นอยู่กับ B ให้ดำเนินการ _load () บน b.js ที่โมดูล A ขึ้นอยู่กับ
โมดูล B จะถูกดาวน์โหลดและวิธีการนิยาม jQuery จะถูกดำเนินการก่อน เนื่องจาก jQuery ไม่ได้ขึ้นอยู่กับโมดูลหลังจากการโทรกลับ วิธีการโทรหาวิธี CB
เมื่อ B ถูกนำไปใช้ในกระบวนการเดียวกันกับ A โมดูล C จะถูกดาวน์โหลด ในที่สุด C, B, โมดูลจะถูกดาวน์โหลดและดำเนินการและหลังจาก ONLOAD เสร็จสมบูรณ์วิธี CB จะถูกเรียกด้วย (First C จากนั้น B จากนั้น C จากนั้น C)
หลังจากโมดูลทั้งหมดพร้อมวิธีการโทรกลับ 2 จะถูกเรียก
ในที่สุดการเรียกกลับถูกเรียกว่า back2 และวิธีการคอมไพล์ของโมดูล A และ jQuery จะถูกดำเนินการ:
ขั้นแรกให้รวบรวมโมดูล A.JS และดำเนินการฟังก์ชันของโมดูล เนื่องจาก A มี (b.js) ในนั้นมันจะดำเนินการฟังก์ชั่นของโมดูล b
ฟังก์ชั่นของโมดูล A เริ่มดำเนินการ
ฟังก์ชั่นของโมดูล B เริ่มดำเนินการ
ฟังก์ชั่นของโมดูล C เริ่มดำเนินการ
การดำเนินการฟังก์ชั่นของโมดูล C เสร็จสมบูรณ์
การดำเนินการฟังก์ชั่นของโมดูล B เสร็จสมบูรณ์
ฟังก์ชั่นการดำเนินการของโมดูล A เสร็จสมบูรณ์
ในที่สุดก็ดำเนินการฟังก์ชั่นของ jQuery
หลังจากการรวบรวมแล้วเรียกใช้งานการโทรกลับ 1 และคุณสามารถใช้วัตถุ A และ jQuery
PS: เวอร์ชัน SEAJS ได้รับการอัปเดตแล้วและตอนนี้ไม่มีวิธี _compile (ทุกคนไปดูด้วยตัวคุณเองฉันก็อยากเห็นมันด้วย)
มาพูดคุยเกี่ยวกับกระบวนการรวบรวมโมดูล SEAJS
ก่อนอื่นการรวบรวม A.JS
การคัดลอกรหัสมีดังนี้:
module.prototype._compile = function () {
126 var module = this
127 // หากคอมไพล์โมดูลแล้วกลับโมดูลส่งออกโดยตรง
128 if (module.status === status.compiled) {
129 return module.exports
130}
133 // 1. ไฟล์โมดูลคือ 404
134 // 2. ไฟล์โมดูลไม่ได้เขียนด้วยรูปแบบโมดูลที่ถูกต้อง
135 // 3. กรณีข้อผิดพลาดอื่น ๆ
136 // นี่คือข้อยกเว้นบางอย่างที่จะจัดการแล้วกลับ NULL โดยตรง
137 ถ้า (module.status <status.saved &&! hasmodifiers (โมดูล)) {
138 Return Null
139}
140 // เปลี่ยนสถานะโมดูลเป็นการรวบรวมซึ่งหมายความว่าโมดูลกำลังถูกรวบรวม
141 module.status = status.compiling
142
143 // การใช้งานภายในของโมดูลเป็นวิธีที่ใช้ในการรับอินเทอร์เฟซที่จัดทำโดยโมดูลอื่น ๆ (เรียกว่า submodules) และทำงานแบบซิงโครนัส
144 ฟังก์ชั่นต้องการ (id) {
145 // เส้นทางเส้นทางของโมดูลตาม ID
146 var uri = resolve (id, module.uri)
147 // รับโมดูลจากโมดูลแคช (โปรดทราบว่าการพึ่งพาของ submodule เป็นโมดูลหลักได้รับการดาวน์โหลด)
148 var child = cachedmodules [uri]
149
150 // เพียงแค่คืนค่า null เมื่อ URI ไม่ถูกต้อง
151 // ถ้าเด็กว่าง
152 ถ้า (! เด็ก) {
153 Return Null
154}
155
156 // หลีกเลี่ยงการโทรแบบวงกลม
157 // หากสถานะของ submodule เป็นสถานะการคอมไพล์, ส่งคืน child.exports โดยตรงเพื่อหลีกเลี่ยงการรวบรวมโมดูลซ้ำเนื่องจากการพึ่งพาแบบวงกลม
158 ถ้า (child.status === สถานะการคอมไพล์) {
159 return child.exports
160}
161 // ชี้ไปที่โมดูลที่เรียกโมดูลปัจจุบันระหว่างการเริ่มต้น ขึ้นอยู่กับคุณสมบัตินี้คุณสามารถรับสแต็กการโทรได้เมื่อมีการเริ่มต้นโมดูล
162 child.parent = โมดูล
163 // ส่งคืนโมดูลส่งออกของเด็กที่รวบรวม
164 return child._compile ()
165}
166 // ใช้ภายในเพื่อโหลดโมดูลแบบอะซิงโครนัสและเรียกใช้การโทรกลับที่ระบุหลังจากการโหลดเสร็จสมบูรณ์
167 require.async = function (ids, callback) {
168 Module._USE (IDS, CallBack)
169}
170 // ใช้กลไกการแก้ไขเส้นทางภายในระบบโมดูลเพื่อแยกวิเคราะห์และส่งคืนเส้นทางโมดูล ฟังก์ชั่นนี้ไม่ได้โหลดโมดูลและส่งคืนเส้นทางสัมบูรณ์ที่แยกวิเคราะห์เท่านั้น
171 require.resolve = function (id) {
172 Return Resolve (id, module.uri)
173}
174 // ผ่านคุณสมบัตินี้คุณสามารถดูโมดูลทั้งหมดที่โหลดโดยระบบโมดูล
175 // ในบางกรณีหากคุณต้องการโหลดโมดูลใหม่คุณสามารถรับ URI ของโมดูลแล้วลบข้อมูลโดยลบต้องการ. cache [uri] สิ่งนี้จะได้รับการรับรองอีกครั้งในครั้งต่อไปที่คุณใช้
176 ต้องการ. cache = cachedmodules
177
178 // ต้องการเป็นวิธีการที่จะได้รับอินเทอร์เฟซที่จัดทำโดยโมดูลอื่น ๆ
179 module.require = ต้องการ
180 // การส่งออกเป็นวัตถุที่ให้อินเทอร์เฟซโมดูลด้านนอก
181 module.exports = {}
182 Var Factory = Module.Factory
183
184 // เมื่อโรงงานเป็นฟังก์ชั่นมันแสดงถึงตัวสร้างของโมดูล โดยการดำเนินการวิธีนี้คุณสามารถรับอินเทอร์เฟซที่จัดทำโดยโมดูลไปด้านนอก
185 ถ้า (util.isfunction (โรงงาน)) {
186 Compilestack.push (โมดูล)
187 RuninModuleContext (โรงงาน, โมดูล)
188 compilestack.pop ()
189}
190 // เมื่อโรงงานเป็นประเภทที่ไม่ทำงานเช่นวัตถุสตริง ฯลฯ อินเตอร์เฟสที่แสดงถึงโมดูลคือวัตถุสตริงและค่าอื่น ๆ
191 // ตัวอย่าง: define ({"foo": "bar"});
192 // ตัวอย่าง: define ('ฉันเป็นเทมเพลตชื่อของฉันคือ {{name}}.');
193 อื่น ๆ ถ้า (โรงงาน! == ไม่ได้กำหนด) {
194 module.exports = โรงงาน
195}
196
197 // เปลี่ยนสถานะโมดูลเป็นคอมไพล์ซึ่งหมายความว่าโมดูลได้ถูกรวบรวม
198 module.status = สถานะคอมไพล์
199 // ดำเนินการปรับเปลี่ยนโมดูลอินเตอร์เฟสผ่าน seajs.modify ()
200 Execmodifiers (โมดูล)
201 Return Module.exports
202}
การคัดลอกรหัสมีดังนี้:
if (util.isfunction (โรงงาน)) {
186 Compilestack.push (โมดูล)
187 RuninModuleContext (โรงงาน, โมดูล)
188 compilestack.pop ()
189}
นี่คือการเริ่มต้นของโมดูล export วิธี RuninModuleContext:
การคัดลอกรหัสมีดังนี้:
// ดำเนินการรหัสโมดูลตามบริบทของโมดูล
489 ฟังก์ชั่น runinModuleContext (FN, โมดูล) {
490 // ส่งผ่านสองพารามิเตอร์ที่เกี่ยวข้องกับโมดูลและโมดูลเอง
491 // การส่งออกใช้เพื่อเปิดเผยอินเทอร์เฟซ
492 // จำเป็นต้องใช้เพื่อให้ได้โมดูลขึ้นอยู่กับ (ซิงโครนัส) (คอมไพล์)
493 var ret = fn (module.require, module.exports, โมดูล)
494 // รองรับรูปแบบอินเตอร์เฟสของการเปิดรับผลตอบแทนเช่น::
495 // return {
496 // fn1: xx
497 //, fn2: xx
498 // ...
499 //}
500 ถ้า (ret! == ไม่ได้กำหนด) {
501 module.exports = ret
502}
503}
ดำเนินการวิธีการฟังก์ชั่นใน a.js และจากนั้น var b = ต้องการ ("b.js") จะถูกเรียก
วิธีการที่ต้องการจะส่งคืนค่าการส่งคืนของวิธีการคอมไพล์ของ B และมี var c = ต้องการ ('c.js') ในโมดูล B
ในเวลานี้วิธีการคอมไพล์ของ C จะถูกเรียกและจากนั้นจะเรียกฟังก์ชันของ C ใน C หากวัตถุจะถูกเปิดเผยหรือส่งคืนวัตถุส่งคืน C การส่งออกของโมดูล C จะเป็นการส่งออก = c หรือโมดูลโดยตรง export = c; ในระยะสั้นโมดูล c.export = c จะถูกส่งกลับในตอนท้าย; ดังนั้น var c = โมดูล c.export = c ในโมดูล B คุณสามารถใช้ตัวแปร C เพื่อเรียกวิธีการและคุณสมบัติของวัตถุ C ในโมดูล C
โดยการเปรียบเทียบโมดูล A สามารถเรียกคุณสมบัติและวิธีการของวัตถุ B ในโมดูล B ในที่สุด
ไม่ว่าโมดูลใดตราบใดที่คุณใช้โมดูลโมดูล = โมดูล XX โมดูลอื่น ๆ สามารถใช้ต้องการ ("โมดูล XX") เพื่อเรียกใช้วิธีการต่าง ๆ ในโมดูล XX
สถานะโมดูลสุดท้ายจะกลายเป็น module.status = status.compiled
การคัดลอกรหัสมีดังนี้:
module.prototype._use = function (ids, callback) {
var uris = resolve (ids, this.uri); // ความละเอียด ['./a' ,'jquery']
this._load (uris, function () {// เรียกที่อยู่ของโมดูลที่แยกวิเคราะห์และ jQuery [url1, url2] และเรียกใช้วิธี _load
//util.map: ให้สมาชิกข้อมูลทั้งหมดดำเนินการฟังก์ชั่นที่ระบุในแต่ละครั้งและส่งคืนอาร์เรย์ใหม่ซึ่งเป็นผลมาจากการเรียกใช้การเรียกกลับของสมาชิกอาร์เรย์ดั้งเดิม
var args = util.map (uris, function (uri) {
กลับ uri? CachedModules [uri] ._ compile (): null; // ถ้า url มีอยู่ให้เรียกวิธี _compile
-
if (callback) {callback.apply (null, args)}
-
-
ในเวลานี้ args = [โมดูล a.export, โมดูล jQuery.export];
การคัดลอกรหัสมีดังนี้:
sejs.use (['./ a', 'jQuery'], ฟังก์ชั่น (a, $) {
var num = aa;
$ ('#j_a') ข้อความ (num);
-
ในเวลานี้ A และ $ ในฟังก์ชั่นคือโมดูล A.Export และโมดูล jQuery.export
เพราะตอนนี้ฉันกำลังศึกษาซอร์สโค้ด jQuery และการออกแบบกรอบ JQuery ฉันแบ่งปันประสบการณ์บางอย่าง:
ซอร์สโค้ด jQuery ฉันได้อ่านการวิเคราะห์ทางออนไลน์มากมาย แต่ฉันไม่สามารถอ่านได้อีกต่อไปเมื่อฉันดู มันไม่ได้มีความหมายมากดังนั้นฉันขอแนะนำการวิเคราะห์ซอร์สโค้ด jQuery ของ Miaowei
การออกแบบเฟรมเวิร์ก JavaScript ของ Situ Zhengmei นั้นยาก แต่หลังจากการอ่านอย่างระมัดระวังคุณจะกลายเป็นวิศวกรอาวุโส
ฉันขอแนะนำให้เรียนรู้และใช้ทะเลของ Yu Bo หลังจากนั้นมันถูกสร้างขึ้นโดยชาวจีนเอง โครงการใหม่หรือการสร้างใหม่ของ บริษัท ของเราจะดำเนินการโดยใช้ SEAJS
ถัดไปคือการอ่านซอร์สโค้ดอย่างเข้มข้นของแฮนด์บาร์แบบแยกส่วนและ Backbone MVC หรือ MVVM Angular ที่นี่ฉันหวังว่าจะมีคนให้คำแนะนำเกี่ยวกับหนังสือเว็บไซต์และวิดีโอที่จะเรียนรู้ได้อย่างรวดเร็ว