/**
 * Promise扩展模块
 * @date 2022-08
 * @author 何华东
 */

/**
 * 异步锁
 */
class AsyncLock {
    disable: any;
    promise: Promise<void> = Promise.resolve();

    enable() {
        this.promise = new Promise(resolve => this.disable = resolve);
    }
}

/**
 * 异步方法同步执行器 `异步锁`
 * 
 * ```ts
 * import { Sync } from "refs/nslib";
 * 
 * //去掉注释
 * //@Sync()
 * async function test(){
 *   //todo...
 * }
 * 
 * ```
 */
export function Sync(): MethodDecorator {
    return function (target: Object, propertyKey: string, descriptor: PropertyDescriptor) {
        let method = descriptor.value;
        let lock = new AsyncLock();

        descriptor.value = async function (...args) {
            await lock.promise;
            lock.enable();

            try {
                return await method.apply(this, args);
            } catch (error) {
                throw error;
            } finally {
                lock.disable();
            }
        }
    }
}

/**
 * 延迟
 */
export function delay(ms?: number): Promise<void> {
    return new Promise(resolve => {
        setTimeout(resolve, ms);
    });
}