เมื่อปีที่แล้วหลายโครงการจำเป็นต้องใช้ JavaScript เพื่อล็อคดังนั้นฉันจึงเขียนโครงการที่คล้ายกันสองสามอันซึ่งหนึ่งในนั้น:
คัดลอกรหัสรหัสดังนี้:
// เผยแพร่โดย Indream Luo
// contal: [email protected]
// เวอร์ชัน: ภาษาจีน 1.0.0
! ฟังก์ชั่น ($) {
window.indream = window.indream || {};
$ .indream = Indream;
indream.async = {
-
//ล็อค
// ล็อค: จำนวนล็อค
// การกระทำ: วิธีการดำเนินการหลังจากปลดล็อค
-
ล็อค: ฟังก์ชั่น (ล็อค, การกระทำ) {
$ .indream.async.waitings [ล็อค] = $ .indream.async.waitings [ล็อค] || [];
$ .indream.async. Waitings [Lock] .push (การกระทำ);
// หากไม่ได้ใช้การล็อคการกระทำปัจจุบันจะบล็อกล็อค
if (! $. indream.async.lockstatus [ล็อค] && การกระทำ) {
$ .indream.async.lockstatus [ล็อค] = true;
if (arguments.length> 2) {{
var args = 'อาร์กิวเมนต์ [2]';
สำหรับ (var i = 3; i <arguments.length; i ++) {
args + = ', อาร์กิวเมนต์ [' + i + ']';
-
eval ('$. indream.async.action.call (การกระทำ,' + args + ')');
} อื่น {
$ .indream.async.action.call (การกระทำ);
-
-
-
-
// ปลดล็อก
// ล็อค: จำนวนล็อค
-
releaselock: ฟังก์ชั่น (ล็อค) {
$ .indream.async. Waitings [Lock] .shift ();
// หากคิวรอเป็นวัตถุคิวรอจะถูกดำเนินการมิฉะนั้นปลดล็อค
if ($ .indream.async.waitings [lock] .length) {
$ .indream.async. Waitings [Lock] [0] ();
} อื่น {
$ .indream.async.lockstatus [ล็อค] = เท็จ;
-
-
-
// สถานะล็อค
-
Lockstatus: [],
-
// รอให้กิจกรรมเสร็จสมบูรณ์
// ล็อค: การเข้ารหัสล็อคการเข้ารหัสเดียวกันจะถูกรวมเข้ากับลำดับทริกเกอร์
-
รอ: ฟังก์ชั่น (ล็อค, การกระทำ) {
$ .indream.async.waitings [รหัส] = $ .indream.async.waitings [รหัส] || [];
$ .indream.async. Waitings [Code] .push (การกระทำ);
-
-
// รอลำดับ
-
รอ: [],
-
// ข้อมูลแคช
-
การกระทำ: {
-
// วิธีการที่เกี่ยวข้องสำหรับการตรวจสอบและการโทรกลับ
-
โทรกลับ: {
-
//เฝ้าสังเกต
-
ฟัง: ฟังก์ชั่น (ActionName, callback) {
var list = $ .indream.async.action.calllback.list;
รายการ [actionName] = รายการ [ActionName] || [];
รายการ [ActionName] .PUSH (การโทรกลับ);
-
-
-
-
การโทร: ฟังก์ชัน (ActionName, args) {
var list = $ .indream.async.action.calllback.list;
if (list [actionName] && list [actionName] .length) {
สำหรับ (var i ในรายการ [actionName]) {
$ .indream.async.action.call (รายการ [activityName] [i], args);
-
-
-
-
// รายการโทรกลับที่มีอยู่
-
รายการ: []
-
-
// ไม่ว่าจะมีวิธีการหรือไม่และพารามิเตอร์มีอยู่เพื่อเลือกวิธีการดำเนินการที่เหมาะสม
-
โทร: ฟังก์ชั่น (การกระทำ) {
ถ้า (การกระทำ) {
if (arguments.length> 1) {{
var args = 'อาร์กิวเมนต์ [1]';
สำหรับ (var i = 2; i <arguments.length; i ++) {
args + = ', อาร์กิวเมนต์ [' + i + ']';
-
eval ('การกระทำ (' + args + ')');
} อื่น {
การกระทำ ();
-
-
-
-
-
} (window.jquery);
องค์ประกอบหลายอย่างของการล็อคซึ่งกันและกันคือ:
•ล็อคและปลดล็อก
•รอคิว
•วิธีการดำเนินการ
การใช้งานล็อคข้างต้น:
คัดลอกรหัสรหัสดังนี้:
// กำหนดชื่อของล็อค
var lock = 'scrolltop ()';
// ใช้ล็อค
$ .indream.async.lock (ล็อค, ฟังก์ชัน () {{) {
var scrolltop = $ (หน้าต่าง)
ตัวจับเวลา var;
Varfulltime = 100;
สำหรับ (timer = 0; ตัวจับเวลา <= เต็มเวลา; ตัวจับเวลา += 10) {
Settimeout ('$ (หน้าต่าง) ScrollTop (' + (ScrollTop * (เต็มเวลา -Timer) / เต็มเวลา) + ');', ตัวจับเวลา);
-
// ปล่อยล็อค
settimeout ('$. indream.async.releaselock ("' + lock + '");', เต็มเวลา);
-
เกี่ยวกับการตระหนักถึงเวลานี้อธิบายสั้น ๆ
-ล็อคสปินหรือจำนวนสัญญาณ
JavaScript ไม่มีฟังก์ชั่นล็อคดังนั้นล็อคจะถูกนำไปใช้ในระดับสูง
ตามหลักการของ JavaScript Single -Thread ทรัพยากรเธรดของ JS มี จำกัด มากและไม่เหมาะสำหรับการใช้ล็อคแบบหมุนดังนั้นฉันเลือกที่จะใช้เซมาฟอร์
แน่นอนว่าตัวล็อคตัวเองเป็นเช่นนี้แน่นอนว่าทำในขณะที่มีประโยชน์มากกว่า:
คัดลอกรหัสรหัสดังนี้:
ในขณะที่ (จริง) {
// ทำอะไร ...
-
สิ่งนี้จะต้องใช้ประโยชน์จากเธรดเต็มอย่างหลีกเลี่ยงไม่ได้ แน่นอนถ้าจำเป็นคุณสามารถเลือกการรวมกันของ setInterval และ clearinterval เพื่อให้ได้มันและเอฟเฟกต์จะดี
วิธีการของจำนวนสัญญาณนั้นง่ายที่นี่และหลักการนั้นง่ายพอเพียงสั้น ๆ คำสั่งของการทำงานประมาณ:
•กดส่วนโค้ด (การดำเนินการโทรกลับ) ไปยังคิวรอ
•ตรวจสอบว่ามีการล็อคปัจจุบันหรือไม่
•เมื่อล็อคถูกปล่อยออกมาการปรับครั้งต่อไปจะถูกส่งผ่านในคิวรอและล็อคจะถูกส่งผ่านไปและดำเนินการ
-ในการเปิดตัวอัตโนมัติหรือการเปิดตัวด้วยตนเอง
แน่นอนว่าวิธีที่สะดวกสบายที่สุดคือมันจะถูกปล่อยออกมาโดยอัตโนมัติเมื่อมีการดำเนินการโปรแกรมปัจจุบัน แต่นี่ไม่ใช่เรื่องง่ายเพราะสถานการณ์อื่น ๆ จำเป็นต้องปรับแต่งการเปิดตัวฉาก
สิ่งที่ใช้ในตัวเองคือวิธีการแบบอะซิงโครนัสดังนั้นเนื้อหาแบบอะซิงโครนัสอื่น ๆ มักจะปรากฏขึ้นเช่น Ajax และ jQuery Animation ในเวลานี้การเปิดตัวอัตโนมัติไม่เป็นไปตามความต้องการเพราะในความเป็นจริงการดำเนินการ "การดำเนินการ" ที่แท้จริงคือหลังจากการโทรกลับแบบอะซิงโครนัสภายในนั่นคือโดยทั่วไปแล้วนักพัฒนาสามารถเข้าใจตัวเองได้ดังนั้นพวกเขาจึงเลือกที่จะปล่อยที่นี่
อย่างไรก็ตามยังมีข้อบกพร่องนั่นคือการเปิดตัวซ้ำ ๆ
จะเห็นได้ว่าวัตถุล็อคทั้งหมดเป็นสาธารณะหรือวัตถุทั้งหมดของ JS เป็นสาธารณะเว้นแต่ว่าตัวแปรท้องถิ่นจะถูกแยกออกจากระดับการเข้าถึง อย่างไรก็ตาม "ล็อค" เองเป็นทรัพยากรสาธารณะดังนั้นจึงไม่มีวิธีจัดการกับมัน
การเพิ่มประสิทธิภาพที่สามารถทำได้ที่นี่ควรล็อคด้วยชื่อล็อคสาธารณะเช่น SetInterval และ ClearInterval และปลดล็อคด้วยรหัสล็อคส่วนตัวสามารถป้องกันการเปิดตัวซ้ำ ๆ อย่างไรก็ตามไม่มีในรหัสเก่าด้านบนคาดว่าจะใช้ในไม่ช้า