Last year, several projects needed to use JavaScript to lock, so I wrote a few similar ones, one of which:
Copy code code as follows:
// Published by Indream Luo
// contal: [email protected]
// version: chinese 1.0.0
! Function ($) {
window.indream = window.indream || {};
$ .indream = indream;
indream.async = {
//
//Lock
// lock: the number of the lock
// action: The way to execute after unlocking
//
lock: function (lock, action) {
$ .indream.async.waitings [lock] = $ .indream.async.waitings [lock] || [];
$ .indream.async.waitings [lock] .push (action);
// If the lock is not used, the current action blocks the lock
if (! $. Indream.async.Lockstatus [lock] && action) {
$ .indream.async.Lockstatus [lock] = true;
if (Arguments.length> 2) {{
var args = 'arguments [2]';
for (var I = 3; I <arguments.length; i ++) {
args + = ', arguments [' + i + ']';
}
Eval ('$. Indream.async.Action.call (action,' + args + ')');
} Else {
$ .indream.async.Action.call (action);
}
}
},
//
// Unlock
// lock: the number of locks
//
ReleaseLock: Function (LOCK) {
$ .indream.async.waitings [lock] .shift ();
// If the waiting queue is object, the waiting queue is executed, otherwise unlock
if ($ .indream.async.waitings [lock] .Length) {
$ .indream.async.waitings [lock] [0] ();
} Else {
$ .indream.async.Lockstatus [lock] = false;
}
},
//
// Lock status
//
lockstatus: [],
//
// Waiting for the event to complete
// Lock: Lock coding, the same encoding will be integrated into a sequence, triggering
//
WAIT: FUNCTION (Lock, Action) {
$ .indream.async.waitings [code] = $ .indream.async.waitings [code] || [];
$ .indream.async.waitings [code] .push (action);
},
//
// Waiting for the sequence
//
waitings: [],
//
// Data cache
//
ACTION: {
//
// Related methods for monitoring and callback
//
callback: {
//
//monitor
//
Listen: Function (ActionName, Callback) {
var list = $ .indream.async.ACTION.CALLLBACK.List;
list [actionName] = list [actionName] || [];
list [actionName] .push (callback);
},
//
//
//
Call: Function (ACTIONNAME, ARGS) {
var list = $ .indream.async.ACTION.CALLLBACK.List;
if (list [actionName] && list [actionName] .Length) {
for (var I in list [actionName]) {
$ .indream.async.Action.Call (list [activityName] [i], args);
}
}
},
//
// The existing callback list
//
List: []
},
//
// Whether the method exists and whether the parameter exists to choose the appropriate execution method
//
Call: Function (Action) {
if (action) {
if (Arguments.length> 1) {{
var args = 'arguments [1]';
for (var I = 2; I <arguments.length; i ++) {
args + = ', arguments [' + i + ']';
}
EVAL ('Action (' + ARGS + ')');
} Else {
action ();
}
}
}
}
}
} (window.jquery);
Several elements of mutual locking are:
• Lock and unlock
• Waiting for queue
• Execution method
Usage of the above locks:
Copy code code as follows:
// Define the name of the lock
var lock = 'scrolltop ()';
// Use the lock
$ .indream.async.Lock (LOCK, Function () {{) {
var scrolltop = $ (window). Scrolltop ();
var timer;
varfulltime = 100;
for (timer = 0; timer <= fulltime; timer += 10) {
settimeout ('$ (Window). Scrolltop (' + (Scrolltop * (FullTime -Timer) / Fulltime) + ');', Timer);
}
// Release the lock
settimeout ('$. Indream.async.releaselock ("' + Lock + '");', FullTime);
});
Regarding the realization of this time, briefly explain.
-The spin lock or signal amount
JavaScript has no lock function, so the locks are implemented at high levels.
According to the principle of JavaScript single -thread, JS's thread resources are very limited, and it is not suitable for using spin locks, so I chose to use the semaphore.
The self -spin lock is roughly like this, of course, Do While is more useful:
Copy code code as follows:
While (true) {
// Do something ...
}
This must inevitably take advantage of the full thread. Unfortunately, JS has only one thread that can be used for execution, so this is not applicable. Of course, if necessary, you can choose the combination of SetInterval and Clearinterval to achieve it, and the effect will be good.
The method of the signal amount is simple here, and the principle is simple, just as short as the code. The order of work is roughly:
• Push the code segment (the callback Action) into the waiting queue
• Determine whether the current lock is held. If you are held, you will wait to release it, otherwise you will get the lock and execute the callback
• When the lock is released, the next adjustment is passed in the waiting queue, and the lock is passed to it and executed
-In automatic release or manual release
The most comfortable way is, of course, it is automatically released when the current program is executed, but this is not easy, because more situations need to customize the release of the scene.
What is used in itself is the asynchronous method, so other asynchronous contents usually appear, such as AJAX and jQuery animation. At this time, the automatic release does not meet the demand, because in fact, the real "execution" is that after the asynchronous callback within it, that is, basically only the developers can grasp themselves, so they choose to release it here.
However, there are still defects, that is, repeated release.
It can be seen that all lock objects are public, or that all the objects of JS are public, unless the local variable is isolated at the access level. However, the "lock" itself is a public resource, so there is no way to deal with it.
The optimization that can be done here should be locks with a public lock name like SetInterval and Clearinterval, and unlock with private lock IDs can prevent repeated release. However, there is no in the old code above, it is estimated that it will be used soon.