55 lines
1.6 KiB
TypeScript
55 lines
1.6 KiB
TypeScript
const THREAD_ID = `${Math.floor(Math.random() * 1000)}-${Date.now()}`;
|
|
|
|
const nextTick = fn => {
|
|
setTimeout(fn, 0);
|
|
};
|
|
|
|
/**
|
|
* 利用共享区域实现快速锁
|
|
*/
|
|
class LockUtils {
|
|
private _keyX: string;
|
|
private _keyY: string;
|
|
private setItem;
|
|
private getItem;
|
|
private removeItem;
|
|
|
|
constructor(key) {
|
|
this._keyX = `mutex_key_${key}_X`;
|
|
this._keyY = `mutex_key_${key}_Y`;
|
|
this.setItem = egret.localStorage.setItem.bind(localStorage);
|
|
this.getItem = egret.localStorage.getItem.bind(localStorage);
|
|
this.removeItem = egret.localStorage.removeItem.bind(localStorage);
|
|
}
|
|
|
|
public lock() {
|
|
return new Promise((resolve, reject) => {
|
|
const fn = () => {
|
|
this.setItem(this._keyX, THREAD_ID);
|
|
if (!this.getItem(this._keyY) === null) {
|
|
// restart
|
|
nextTick(fn);
|
|
}
|
|
this.setItem(this._keyY, THREAD_ID);
|
|
if (this.getItem(this._keyX) !== THREAD_ID) {
|
|
// delay
|
|
setTimeout(() => {
|
|
if (this.getItem(this._keyY) !== THREAD_ID) {
|
|
// restart
|
|
nextTick(fn);
|
|
return;
|
|
}
|
|
// critical section
|
|
resolve();
|
|
this.removeItem(this._keyY);
|
|
}, 10);
|
|
} else {
|
|
resolve();
|
|
this.removeItem(this._keyY);
|
|
}
|
|
};
|
|
|
|
fn();
|
|
});
|
|
}
|
|
} |