작년에 몇몇 프로젝트는 JavaScript를 사용하여 잠금해야했기 때문에 몇 가지 비슷한 프로젝트를 썼습니다. 그 중 하나는 다음과 같습니다.
다음과 같이 코드 코드를 복사하십시오.
// Indream Luo에 의해 게시 됨
// contal : [email protected]
// 버전 : 중국어 1.0.0
기능 ($) {
Window.indReam = Window.indReam || {};
$ .indReam = IndReam;
indReam.async = {
//
//잠그다
// 잠금 : 자물쇠 수
// 작업 : 잠금 해제 후 실행 방법
//
잠금 : 함수 (잠금, 동작) {
$ .indream.async.waitings [lock] = $ .indream.async.waitings [lock] ||;
$ .indream.async.waitings [lock] .push (action);
// 잠금 장치가 사용되지 않으면 현재 동작이 잠금을 차단합니다.
if (! $. indream.async.lockstatus [lock] && action) {
$ .indream.async.lockstatus [lock] = true;
if (arguments.length> 2) {{
var args = '인수 [2];
for (var i = 3; i <arguments.length; i ++) {
args + = ', 인수 [' + i + ']';
}
eval ( '$. indream.async.action.call (action,' + args + '));
} 또 다른 {
$ .indream.async.action.call (action);
}
}
},
//
// 잠금 해제
// 잠금 : 자물쇠 수
//
릴리스 : 함수 (잠금) {
$ .indream.async.waitings [lock] .shift ();
// 대기 대기열이 오브젝트 인 경우 대기 대기열이 실행됩니다. 그렇지 않으면 잠금 해제
if ($ .indream.async.waitings [lock] .length) {
$ .indream.async.waitings [lock] [0] ();
} 또 다른 {
$ .indream.async.lockstatus [lock] = false;
}
},
//
// 상태 잠금 상태
//
Lockstatus : [],
//
// 이벤트가 완료되기를 기다리고 있습니다
// 잠금 : 잠금 코딩, 동일한 인코딩이 시퀀스로 통합되어 트리거링
//
대기 : 기능 (잠금, 동작) {
$ .indream.async.waitings [code] = $ .indream.async.waitings [code] ||;
$ .indream.async.waitings [code] .push (action);
},
//
// 시퀀스를 기다리고 있습니다
//
대기자 : [],
//
// 데이터 캐시
//
행동: {
//
// 모니터링 및 콜백 관련 방법
//
콜백 : {
//
//감시 장치
//
듣기 : 함수 (ActionName, Callback) {
var list = $ .indream.async.action.calllback.list;
List [ActionName] = List [ActionName] ||;
List [ActionName] .push (콜백);
},
//
//
//
전화 : 함수 (ActionName, Args) {
var list = $ .indream.async.action.calllback.list;
if (list [actionName] && list [actionName] .length) {
for (list [actionname]) {var i
$ .indream.async.action.call (list [activityName] [i], args);
}
}
},
//
// 기존 콜백 목록
//
목록: []
},
//
// 메소드가 존재하는지 및 매개 변수가 적절한 실행 방법을 선택할 수 있는지 여부
//
전화 : 함수 (action) {
if (action) {
if (arguments.length> 1) {{
var args = '인수 [1];
for (var i = 2; i <arguments.length; i ++) {
args + = ', 인수 [' + i + ']';
}
평가 ( 'action (' + args + ')');
} 또 다른 {
행동 ();
}
}
}
}
}
} (window.jquery);
상호 잠금의 몇 가지 요소는 다음과 같습니다.
• 잠금 및 잠금 해제
• 대기열을 기다리고 있습니다
• 실행 방법
위의 잠금 장치 사용 :
다음과 같이 코드 코드를 복사하십시오.
// 잠금의 이름을 정의합니다
var lock = 'scrolltop ()';
// 잠금을 사용합니다
$ .indream.async.lock (잠금, function () {{) {
var scrolltop = $ (창);
var 타이머;
varfulltime = 100;
for (timer = 0; timer <= 풀 타임; 타이머 += 10) {
settimeout ( '$ (창). ScrollTop (' + (ScrollTop * (풀 타임 -타임) / 풀 타임) + ');', 타이머);
}
// 잠금을 해제합니다
settimeout ( '$. indream.async.releaselock ( "' + lock + '");', 풀 타임);
});
이 시간의 실현과 관련하여 간단히 설명하십시오.
-스핀 잠금 또는 신호량
JavaScript에는 잠금 기능이 없으므로 잠금 장치는 높은 레벨로 구현됩니다.
JavaScript 단일 스레드의 원리에 따르면 JS의 스레드 리소스는 매우 제한되어 있으며 스핀 잠금 장치를 사용하는 데 적합하지 않으므로 세마포어를 사용하기로 결정했습니다.
자체 스핀 잠금 장치는 거의 이와 같습니다. 물론 더 유용합니다.
다음과 같이 코드 코드를 복사하십시오.
while (true) {
// 뭔가 ...
}
이것은 불안하게 전체 스레드를 활용해야합니다. 물론 필요한 경우 SetInterval과 Clearinterval의 조합을 선택하여이를 달성 할 수 있으며 그 효과가 좋을 것입니다.
신호량의 방법은 여기에서 간단하며 원리는 코드만큼 짧습니다. 작업 순서는 대략 :
• 코드 세그먼트 (콜백 조치)를 대기 대기열에 밀어 넣습니다.
• 현재 잠금 장치가 유지되는지 확인하면 잠금을 기다리고 콜백을 실행합니다.
• 잠금이 해제되면 다음 조정이 대기 대기열에 전달되고 잠금 장치가 전달되어 실행됩니다.
-자동 릴리스 또는 수동 릴리스
물론 가장 편안한 방법은 현재 프로그램이 실행될 때 자동으로 릴리스되지만 더 많은 상황이 장면 릴리스를 사용자 정의해야하기 때문에 쉽지 않습니다.
그 자체로 사용되는 것은 비동기 방법이므로 Ajax 및 JQuery 애니메이션과 같은 다른 비동기 내용이 나타납니다. 현재 자동 릴리스는 수요를 충족시키지 못합니다. 실제로 실제 "실행"은 비동기 콜백 이후, 기본적으로 개발자만이 스스로 이해할 수 있으므로 여기에서 해제하도록 선택한다는 것입니다.
그러나 여전히 결함이 있습니다. 즉, 반복 방출이 있습니다.
로컬 변수가 액세스 레벨에서 분리되지 않는 한 모든 잠금 객체가 공개되거나 JS의 모든 객체가 공개임을 알 수 있습니다. 그러나 "잠금"자체는 공공 자원이므로 처리 할 방법이 없습니다.
여기서 수행 할 수있는 최적화는 SetInterval 및 Clearinterval과 같은 공개 잠금 이름을 가진 잠금 장치이어야하며 개인 잠금 ID로 잠금 해제하면 반복 된 릴리스를 방지 할 수 있습니다. 그러나 위의 이전 코드에는 없으며 곧 사용될 것으로 추정됩니다.