去年有几个项目需要使用JavaScript互斥锁,所以写了几个类似的,这是其中一个:
//Published by Indream Luo
//Contact: indreamluo@qq.com
//Version: Chinese 1.0.0
!function ($) {
window.indream = window.indream || {};
$.indream = indream;
indream.async = {
//
//锁
//lock: 锁的编号
//action: 解锁后执行的方法
//
lock: function (lock, action) {
$.indream.async.waitings[lock] = $.indream.async.waitings[lock] || [];
$.indream.async.waitings[lock].push(action);
//如果该锁未被使用,则当前action阻塞该锁
if (!$.indream.async.lockStatus[lock] && action) {
$.indream.async.lockStatus[lock] = true;
if (arguments.length > 2) {
var args = 'arguments[2]';
for (var i = 3; i args += ', arguments[' + i + ']';
}
eval('$.indream.async.action.call(action, ' + args + ')');
} else {
$.indream.async.action.call(action);
}
}
},
//
//解锁
//lock: 锁的编号
//
releaseLock: function (lock) {
$.indream.async.waitings[lock].shift();
//如果等待队列有对象,则执行等待队列,否则解锁
if ($.indream.async.waitings[lock].length) {
$.indream.async.waitings[lock][0]();
} else {
$.indream.async.lockStatus[lock] = false;
}
},
//
//锁的状态
//
lockStatus: [],
//
//等待事件完成
//lock:锁编码,相同的编码将被整合成一个序列,触发时同时触发
//
wait: function (lock, action) {
$.indream.async.waitings[code] = $.indream.async.waitings[code] || [];
$.indream.async.waitings[code].push(action);
},
//
//等待序列
//
waitings: [],
//
//数据缓存
//
action: {
//
//监听和回调的相关方法
//
callback: {
//
//监听
//
listen: function (actionName, callback) {
var list = $.indream.async.action.callback.list;
list[actionName] = list[actionName] || [];
list[actionName].push(callback);
},
//
//回调
//
call: function (actionName, args) {
var list = $.indream.async.action.callback.list;
if (list[actionName] && list[actionName].length) {
for (var i in list[actionName]) {
$.indream.async.action.call(list[actionName][i], args);
}
}
},
//
//现有的回调列表
//
list: []
},
//
//根据方法是否存在和参数是否存在选择适当的执行方式
//
call: function (action) {
if (action) {
if (arguments.length > 1) {
var args = 'arguments[1]';
for (var i = 2; i args += ', arguments[' + i + ']';
}
eval('action(' + args + ')');
} else {
action();
}
}
}
}
}
}(window.jQuery);
一个互斥锁的几个元素是:
•锁与解锁
•等待队列
•执行方法
以上锁的用法:
//定义锁的名称
var lock = 'scrollTop()';
//使用锁
$.indream.async.lock(lock, function () {
var scrollTop = $(window).scrollTop();
var timer;
var fullTime = 100;
for (timer = 0; timer setTimeout('$(window).scrollTop(' + (scrollTop * (fullTime - timer) / fullTime) + ');', timer);
}
//释放锁
setTimeout('$.indream.async.releaseLock("' + lock + '");', fullTime);
});
关于这次所的实现,简单说明下。
-自旋锁还是信号量
JavaScript本身没有锁的功能,所以做的锁都是在高层实现的。
依据JavaScript单线程的原理,JS的线程资源十分有限,非常不适合使用自旋锁,所以选择了使用信号量。
自旋锁实现起来的样子大致是这样的,当然do while更多用了:
while(true) {
//do something...
}
这样必然需要占满线程资源,可惜JS只有一条线程可以用来执行,所以这样做十分不适用。当然,有需要可以选择setInterval和clearInterval的组合去实现,效果也会不错。
这里选用了信号量的方式,原理也简单,就如代码那么短。工作的执行顺序大致是:
•把代码段(回调的action)推入等待队列
•判断当前锁是否被持有,如果被持有则等待释放,否则获取该锁,执行回调
•当锁被释放,则在等待队列中shift出下一个回调,将锁传递给它并执行
-自动释放还是手动释放
看起来最舒服的方式当然是锁住之后当当前程序执行完就自动释放,不过这样并不容易,因为有更多的情况需要自定义释放场景。
本身使用锁的就是在异步中的方法,所以各种通常也会出现其他异步内容,比如AJAX、jQuery动画。这个时候,自动释放就不符合需求了,因为实际上真正的“执行完毕”是在它内部的异步回调完成后,也就是基本上只有开发人员自己能把握,所以这里选择了手释放。
不过还是有缺陷的,就是重复释放。
可以看到所有的锁的对象都是公有的,或者应该说JS所有对象都是公有的,除非使局部变量在访问级别上进行隔离。不过这里“锁”本身就是个公共资源,所以没办法处理。
这里可以做的优化应该是像setInterval和clearInterval的那样,以公共的锁名称进行加锁,以私有的锁ID进行解锁,就可以防止重复释放了。不过上面这段老代码中没有,估计很快就会用到的了。

Aplikasi JavaScript di dunia nyata termasuk pengaturcaraan sisi pelayan, pembangunan aplikasi mudah alih dan Internet of Things Control: 1. Pengaturcaraan sisi pelayan direalisasikan melalui node.js, sesuai untuk pemprosesan permintaan serentak yang tinggi. 2. Pembangunan aplikasi mudah alih dijalankan melalui reaktnatif dan menyokong penggunaan silang platform. 3. Digunakan untuk kawalan peranti IoT melalui Perpustakaan Johnny-Five, sesuai untuk interaksi perkakasan.

Saya membina aplikasi SaaS multi-penyewa berfungsi (aplikasi edTech) dengan alat teknologi harian anda dan anda boleh melakukan perkara yang sama. Pertama, apakah aplikasi SaaS multi-penyewa? Aplikasi SaaS Multi-penyewa membolehkan anda melayani beberapa pelanggan dari Sing

Artikel ini menunjukkan integrasi frontend dengan backend yang dijamin oleh permit, membina aplikasi edtech SaaS yang berfungsi menggunakan Next.Js. Frontend mengambil kebenaran pengguna untuk mengawal penglihatan UI dan memastikan permintaan API mematuhi dasar peranan

JavaScript adalah bahasa utama pembangunan web moden dan digunakan secara meluas untuk kepelbagaian dan fleksibiliti. 1) Pembangunan front-end: Membina laman web dinamik dan aplikasi satu halaman melalui operasi DOM dan kerangka moden (seperti React, Vue.js, sudut). 2) Pembangunan sisi pelayan: Node.js menggunakan model I/O yang tidak menyekat untuk mengendalikan aplikasi konkurensi tinggi dan masa nyata. 3) Pembangunan aplikasi mudah alih dan desktop: Pembangunan silang platform direalisasikan melalui reaktnatif dan elektron untuk meningkatkan kecekapan pembangunan.

Trend terkini dalam JavaScript termasuk kebangkitan TypeScript, populariti kerangka dan perpustakaan moden, dan penerapan webassembly. Prospek masa depan meliputi sistem jenis yang lebih berkuasa, pembangunan JavaScript, pengembangan kecerdasan buatan dan pembelajaran mesin, dan potensi pengkomputeran IoT dan kelebihan.

JavaScript adalah asas kepada pembangunan web moden, dan fungsi utamanya termasuk pengaturcaraan yang didorong oleh peristiwa, penjanaan kandungan dinamik dan pengaturcaraan tak segerak. 1) Pengaturcaraan yang didorong oleh peristiwa membolehkan laman web berubah secara dinamik mengikut operasi pengguna. 2) Penjanaan kandungan dinamik membolehkan kandungan halaman diselaraskan mengikut syarat. 3) Pengaturcaraan Asynchronous memastikan bahawa antara muka pengguna tidak disekat. JavaScript digunakan secara meluas dalam interaksi web, aplikasi satu halaman dan pembangunan sisi pelayan, sangat meningkatkan fleksibiliti pengalaman pengguna dan pembangunan silang platform.

Python lebih sesuai untuk sains data dan pembelajaran mesin, manakala JavaScript lebih sesuai untuk pembangunan front-end dan penuh. 1. Python terkenal dengan sintaks ringkas dan ekosistem perpustakaan yang kaya, dan sesuai untuk analisis data dan pembangunan web. 2. JavaScript adalah teras pembangunan front-end. Node.js menyokong pengaturcaraan sisi pelayan dan sesuai untuk pembangunan stack penuh.

JavaScript tidak memerlukan pemasangan kerana ia sudah dibina dalam pelayar moden. Anda hanya memerlukan editor teks dan penyemak imbas untuk memulakan. 1) Dalam persekitaran penyemak imbas, jalankan dengan memasukkan fail HTML melalui tag. 2) Dalam persekitaran Node.js, selepas memuat turun dan memasang node.js, jalankan fail JavaScript melalui baris arahan.


Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

ZendStudio 13.5.1 Mac
Persekitaran pembangunan bersepadu PHP yang berkuasa

Muat turun versi mac editor Atom
Editor sumber terbuka yang paling popular

Dreamweaver CS6
Alat pembangunan web visual

MinGW - GNU Minimalis untuk Windows
Projek ini dalam proses untuk dipindahkan ke osdn.net/projects/mingw, anda boleh terus mengikuti kami di sana. MinGW: Port Windows asli bagi GNU Compiler Collection (GCC), perpustakaan import yang boleh diedarkan secara bebas dan fail pengepala untuk membina aplikasi Windows asli termasuk sambungan kepada masa jalan MSVC untuk menyokong fungsi C99. Semua perisian MinGW boleh dijalankan pada platform Windows 64-bit.

MantisBT
Mantis ialah alat pengesan kecacatan berasaskan web yang mudah digunakan yang direka untuk membantu dalam pengesanan kecacatan produk. Ia memerlukan PHP, MySQL dan pelayan web. Lihat perkhidmatan demo dan pengehosan kami.