feat: onload mutex wait.

This commit is contained in:
Rintim 2024-01-07 21:25:53 +08:00
parent 776cae8573
commit 9a81cad2ab
No known key found for this signature in database
GPG Key ID: BE9E1EA615BACFCF
3 changed files with 64 additions and 2 deletions

View File

@ -9,6 +9,7 @@ import { UI as ui } from '../ui/index.js';
import { userAgent } from '../util/index.js';
import * as config from '../util/config.js';
import { gnc } from '../gnc/index.js';
import { Mutex } from '../util/index.js';
export async function onload(resetGameTimeout) {
const libOnload = lib.onload;
@ -821,15 +822,17 @@ function createTouchDraggedFilter() {
/**
* @async
* @param {(() => void | GeneratorFunction)[]} contents
* @param {((function(Mutex): void) | GeneratorFunction)[]} contents
*/
function runCustomContents(contents) {
if (!Array.isArray(contents)) return
const mutex = new Mutex();
const tasks = contents
.filter((fn) => typeof fn === "function")
.map((fn) => gnc.is.generatorFunc(fn) ? gnc.of(fn) : fn) // 将生成器函数转换成genCoroutin
.map((fn) => fn())
.map((fn) => fn(mutex))
return Promise

View File

@ -3,6 +3,7 @@ export const assetURL = typeof nonameInitialized != 'string' || nonameInitialize
export const GeneratorFunction = (function* () { }).constructor;
export const AsyncFunction = (async function () { }).constructor;
export const userAgent = navigator.userAgent.toLowerCase();
export { Mutex } from './mutex.js';
// 我靠循环引用问题在这?
// export * as config from './config.js'

58
noname/util/mutex.js Normal file
View File

@ -0,0 +1,58 @@
/**
*
*/
export class Mutex {
/**
* @type {'locked' | 'unlocked'}
*/
#status;
/**
* @type {null | Promise<void>}
*/
#promise;
/**
* @type {null | function(): void}
*/
#resolve;
constructor() {
this.#status = 'unlocked';
this.#promise = null;
this.#resolve = null;
}
async lock() {
switch (this.#status) {
case 'locked':
await this.#promise;
case 'unlocked':
this.#status = 'locked';
// @ts-ignore
({ promise: this.#promise, resolve: this.#resolve } = Promise.withResolvers())
break;
}
}
unlock() {
if (this.#status === 'unlocked') throw new Error('This Mutex is not locked.');
this.#status = 'unlocked';
if (this.#resolve) this.#resolve();
}
/**
*
* @param {function(): void | Promise<void>} content
*/
async scoped(content) {
try {
await this.lock();
await content();
} finally {
this.unlock();
}
}
}