Tahun lalu, beberapa proyek perlu menggunakan JavaScript untuk mengunci, jadi saya menulis beberapa yang serupa, salah satunya:
Salin kode kode sebagai berikut:
// Diterbitkan oleh Indream Luo
// contal: [email protected]
// Versi: Cina 1.0.0
Fungsi ($) {
window.indream = window.indream || {};
$ .indream = indream;
indream.async = {
//
//Kunci
// Kunci: Jumlah kunci
// Tindakan: Cara untuk mengeksekusi setelah membuka kunci
//
lock: function (lock, action) {
$ .indream.async.Waitings [lock] = $ .indream.async.waitings [lock] || [];
$ .indream.async.waitings [lock] .push (aksi);
// Jika kunci tidak digunakan, aksi saat ini memblokir kunci
if (! $. indream.async.lockstatus [lock] && action) {
$ .indream.async.lockstatus [lock] = true;
if (arguments.length> 2) {{
var args = 'argumen [2]';
untuk (var i = 3; i <arguments.length; i ++) {
args + = ', argumen [' + i + ']';
}
Eval ('$. Indream.async.action.call (action,' + args + ')');
} Kalau tidak {
$ .indream.async.action.call (tindakan);
}
}
},
//
// Buka kunci
// Kunci: Jumlah kunci
//
Releaselock: function (lock) {
$ .indream.async.waitings [lock] .shift ();
// Jika antrian menunggu objek, antrian menunggu dieksekusi, jika tidak buka kunci
if ($ .indream.async.waitings [lock] .length) {
$ .indream.async.Waitings [lock] [0] ();
} Kalau tidak {
$ .indream.async.lockstatus [lock] = false;
}
},
//
// status kunci
//
lockstatus: [],
//
// menunggu acara selesai
// Kunci: Pengkodean kunci, pengkodean yang sama akan diintegrasikan ke dalam urutan, memicu
//
Tunggu: function (lock, action) {
$ .indream.async.Waitings [kode] = $ .indream.async.waitings [kode] || [];
$ .indream.async.Waitings [kode] .push (tindakan);
},
//
// menunggu urutannya
//
Menunggu: [],
//
// cache data
//
TINDAKAN: {
//
// Metode terkait untuk pemantauan dan panggilan balik
//
Callback: {
//
// Monitor
//
Listen: function (actionName, callback) {
var list = $ .indream.async.action.calllback.list;
Daftar [ActionName] = Daftar [ActionName] ||
daftar [ActionName] .push (callback);
},
//
//
//
Call: function (actionName, args) {
var list = $ .indream.async.action.calllback.list;
if (list [actionName] && list [actionName] .length) {
untuk (var i di daftar [actionName]) {
$ .indream.async.action.call (daftar [ActivityName] [i], args);
}
}
},
//
// Daftar panggilan balik yang ada
//
Daftar: []
},
//
// Apakah metode ada dan apakah ada parameter untuk memilih metode eksekusi yang sesuai
//
Call: function (action) {
if (action) {
if (arguments.length> 1) {{
var args = 'argumen [1]';
untuk (var i = 2; i <arguments.length; i ++) {
args + = ', argumen [' + i + ']';
}
Eval ('action (' + args + ')');
} Kalau tidak {
tindakan ();
}
}
}
}
}
} (window.jQuery);
Beberapa elemen penguncian timbal balik adalah:
• Kunci dan buka kunci
• Menunggu antrian
• Metode eksekusi
Penggunaan kunci di atas:
Salin kode kode sebagai berikut:
// Tentukan nama kunci
var lock = 'scrolltop ()';
// Gunakan kunci
$ .indream.async.lock (lock, function () {{) {
var scrolltop = $ (jendela).
var timer;
varfulltime = 100;
untuk (timer = 0; timer <= fulltime; timer += 10) {
setTimeout ('$ (jendela). ScrollTop (' + (scrolltop * (fulltime -timer) / fulltime) + ');', timer);
}
// Lepaskan kunci
setTimeout ('$. indream.async.releaselock ("' + lock + '");', penuh waktu);
});
Mengenai realisasi saat ini, jelaskan secara singkat.
-Mang kunci putaran atau jumlah sinyal
JavaScript tidak memiliki fungsi kunci, sehingga kunci diimplementasikan pada level tinggi.
Menurut prinsip javascript tunggal -thread, sumber daya utas JS sangat terbatas, dan tidak cocok untuk menggunakan kunci spin, jadi saya memilih untuk menggunakan semaphore.
Kunci self -spin kira -kira seperti ini, tentu saja, lakukan sementara lebih berguna:
Salin kode kode sebagai berikut:
While (true) {
// Lakukan sesuatu ...
}
Ini pasti memanfaatkan utas penuh. Tentu saja, jika perlu, Anda dapat memilih kombinasi setInterval dan ClearInterval untuk mencapainya, dan efeknya akan baik.
Metode jumlah sinyal sederhana di sini, dan prinsipnya sederhana, sesingkat kode. Urutan pekerjaan secara kasar:
• Dorong segmen kode (tindakan panggilan balik) ke antrian menunggu
• Tentukan apakah kunci saat ini ditahan.
• Saat kunci dilepaskan, penyesuaian berikutnya dilewatkan dalam antrian menunggu, dan kunci diteruskan ke sana dan dieksekusi
-Dalam rilis otomatis atau rilis manual
Cara yang paling nyaman adalah, tentu saja, secara otomatis dirilis ketika program saat ini dieksekusi, tetapi ini tidak mudah, karena lebih banyak situasi yang perlu menyesuaikan rilis adegan.
Apa yang digunakan dengan sendirinya adalah metode asinkron, sehingga konten asinkron lainnya biasanya muncul, seperti animasi Ajax dan jQuery. Pada saat ini, rilis otomatis tidak memenuhi permintaan, karena pada kenyataannya, "eksekusi" yang sebenarnya adalah bahwa setelah panggilan balik asinkron di dalamnya, yaitu, pada dasarnya hanya pengembang yang dapat memahami diri mereka sendiri, sehingga mereka memilih untuk melepaskannya di sini.
Namun, masih ada cacat, yaitu rilis berulang.
Dapat dilihat bahwa semua objek kunci bersifat publik, atau bahwa semua objek JS bersifat publik, kecuali jika variabel lokal diisolasi pada tingkat akses. Namun, "kunci" itu sendiri adalah sumber daya publik, jadi tidak ada cara untuk menghadapinya.
Optimalisasi yang dapat dilakukan di sini harus dikunci dengan nama kunci publik seperti SetInterval dan ClearInterval, dan membuka kunci dengan ID kunci pribadi dapat mencegah rilis berulang. Namun, tidak ada dalam kode lama di atas, diperkirakan akan segera digunakan.