[220214] 자바스크립트로 Lock만들기
이 코드는 대단하진 않지만 나의 신입시절 추억이 담긴 코드이다.
당시 나는 자바스크립트 비동기 이벤트를 실행 할 때, 특정 비동기 이벤트가 완료되기 전까지 동일한 이벤트를 무시해야 하는 상황을 직면했다. 이것은 아주 자연스러운 기능이다.
하지만 회사 내에서는 이 코드가 아주 중구난방이었다. 글로벌 변수에 상태를 저장해서 이벤트가 완료되었는지 아닌지를 확인하는 코드들도 문제였지만, 꼭 글로벌이 아니더라도 바깥 스코프에 저장하고 완료되면 해당 객체의 프로퍼티에 성공여부를 저장하는 방식이 마음에 들지 않았다. 왜냐하면 nested function 들이 계속 바깥 스코프를 바라보는 것이다. 때때로 로딩이 잘못되면 해당 객체가 만들어지지 않아서 에러가 나기도 했다.
완료는 내부 함수가 했는데 바깥에 있는 프로퍼티를 조작하기 때문에 이리저리 문제가 많이 생겼던 기억이 난다. 나는 이것을 해결하고 싶었다.
그래서 만든 코드가 아래였다.
var Lock = function() { this.L = fase; }; Lock.prototype.isLocked = function() { return this.L; } Lock.prototype.free = function() { return this.L = false; } Lock.prototype.tryLock = function() { if (this.isLocked()) { return false; } else { this.L = true; return true; } }; Lock.wihLock = function(fnc) { var newLock = new Lock(); }
사용방법은 아래와 같다.
Lock.withLock((lock) => { $("#id").click(() => { clickEventAsync(lock); }); }); function clickEventAsync(L) { if (L.tryLock()) { // do sth... L.free(); } }
이 코드에서 핵심은 withLock
이다. 이 Lock을 함수 스코프로 제한하는 것이다.
L.tryLock()
은 락을 점유한다. 성공하면true
를 리턴한다. 성공하면 false를 리턴하고 실행되지 않는다. 재실행을 하는 것은 내가 구현하면 된다.L.free()
로 락을 풀 수 있다. 락을 넘겨줘서 주도권을 실제 수행하는 함수가 대신할 수 있다. 그리고 외부 프로퍼티를 알지 않아도 된다.- 락을 안전하게 공유할 수 있다.
withLock
인자로 들어오는 락을 함께 쓰면 된다.