关于async-await:async异步工具
在es6中的async的语法中,能够参照java并发包实现一些有意思的异步工具,辅助在异步场景(个别指申请)下的开发。因为js是单线程,上面的实现都比java中实现简略 (抛除线程概念)。同时波及到js的执行机制,宏工作,微工作,async,promise相干内容,须要提前具备这些常识。 wait(期待)异步函数中,期待(相当于java线程中的阻塞)一段时间。 实现代码: async function wait(time = 0) { await new Promise(resolve => setTimeout(resolve, time)); // 防止转译成return await, 会在一些safari版本外面报错 return undefined;}模仿应用代码: (async () => { console.time(); await wait(1000); console.timeEnd(); // 输入: default: 1.002s})();Lock(锁)模仿java并发包中的Lock类实现锁操作。 保障同一个锁突围的异步代码执行过程中,同一时刻只有一段代码在执行。 该锁不合乎html5的的异步锁接口,而是提供一个java异步包中Lock接口的简略实现举荐应用场景:多个申请执行过程前,保障同一时刻只有一个token生效验证转换操作。 实现代码: export type Resolve<T = any> = (value: T | PromiseLike<T>) => void;export type Reject = (reason?: any) => void;export interface FlatPromise<T = any> { promise: Promise<T>; resolve: Resolve<T>; reject: Reject;};interface Key { key: number, resolve: Resolve,};/*** 创立一个扁平的promise* @returns Prmise*/function flatPromise<T = any>(): FlatPromise<T> { const result: any = {}; const promise = new Promise<T>((resolve, reject) => { result.resolve = resolve; result.reject = reject; }); result.promise = promise; return result as FlatPromise<T>;}class Lock { keys: Key[] = []; hasLock: boolean = false; idCount: number = 0; constructor() { this.keys = []; this.hasLock = false; this.idCount = 0; } _pushKey(resolve: Resolve) { this.idCount += 1; const key: Key = { key: this.idCount, resolve, }; this.keys.push(key); return key; } _removeKey(key: Key) { const index = this.keys.findIndex(item => item.key === key.key); if (index >= 0) { this.keys.splice(index, 1); } } /** * 获取锁. * 如果以后锁曾经锁定,那么就阻塞以后操作 */ async lock() { if (this.keys.length || this.hasLock) { const { promise, resolve } = flatPromise(); this._pushKey(resolve); await promise; return null; } this.hasLock = true; return null; } /** * 尝试获取锁. * 该函数如果没有指定一个无效的time,则立马返回一个后果:如果获取到锁则为true,反之为false. * 如果指定一个无效的time(time=0无效),则返回一个promise对象,改对象返回的后果为是否获取到锁 * @param time 最长等待时间 */ tryLock(time?: number) { if (time === undefined || Number.isNaN(Math.floor(time)) || time < 0) { if (this.hasLock) { return false; } this.lock(); return Promise.resolve(true); } if (!this.hasLock && !this.keys.length) { this.hasLock = true; return Promise.resolve(true); } const asyncFn = async () => { const { promise, resolve: res } = flatPromise(); const key = this._pushKey(res); setTimeout(() => { this._removeKey(key); key.resolve(false); }, time); const isTimeout = await promise; return isTimeout !== false; }; return asyncFn(); } async lockFn(asyncFn: () => Promise<void>) { await this.lock(); try { await asyncFn(); } finally { this.unlock(); } } /** * 开释锁 */ unlock() { if (this.keys.length === 0 && this.hasLock === true) { this.hasLock = false; return; } if (this.keys.length === 0) { return; } const index = Math.floor(Math.random() * this.keys.length); const key = this.keys[index]; this._removeKey(key); key.resolve(undefined); } toString() { return `${this.keys.length}-${this.hasLock}`; }}模仿应用代码: ...