Add type annotations to AsyncMappedList
This commit is contained in:
parent
0e6c59983f
commit
8466a910da
1 changed files with 34 additions and 45 deletions
|
@ -15,15 +15,14 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {BaseMappedList, runAdd, runUpdate, runRemove, runMove, runReset} from "./BaseMappedList";
|
import {IListObserver} from "./BaseObservableList";
|
||||||
|
import {BaseMappedList, Mapper, Updater, runAdd, runUpdate, runRemove, runMove, runReset} from "./BaseMappedList";
|
||||||
|
|
||||||
export class AsyncMappedList extends BaseMappedList {
|
export class AsyncMappedList<F,T> extends BaseMappedList<F,T,Promise<T>> implements IListObserver<F> {
|
||||||
constructor(sourceList, mapper, updater, removeCallback) {
|
private _eventQueue: AsyncEvent<F>[] | null = null;
|
||||||
super(sourceList, mapper, updater, removeCallback);
|
private _flushing: boolean = false;
|
||||||
this._eventQueue = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubscribeFirst() {
|
onSubscribeFirst(): void {
|
||||||
this._sourceUnsubscribe = this._sourceList.subscribe(this);
|
this._sourceUnsubscribe = this._sourceList.subscribe(this);
|
||||||
this._eventQueue = [];
|
this._eventQueue = [];
|
||||||
this._mappedValues = [];
|
this._mappedValues = [];
|
||||||
|
@ -35,110 +34,100 @@ export class AsyncMappedList extends BaseMappedList {
|
||||||
this._flush();
|
this._flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
async _flush() {
|
async _flush(): Promise<void> {
|
||||||
if (this._flushing) {
|
if (this._flushing) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._flushing = true;
|
this._flushing = true;
|
||||||
try {
|
try {
|
||||||
while (this._eventQueue.length) {
|
while (this._eventQueue!.length) {
|
||||||
const event = this._eventQueue.shift();
|
const event = this._eventQueue!.shift();
|
||||||
await event.run(this);
|
await event!.run(this);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
this._flushing = false;
|
this._flushing = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onReset() {
|
onReset(): void {
|
||||||
if (this._eventQueue) {
|
if (this._eventQueue) {
|
||||||
this._eventQueue.push(new ResetEvent());
|
this._eventQueue.push(new ResetEvent());
|
||||||
this._flush();
|
this._flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onAdd(index, value) {
|
onAdd(index: number, value: F): void {
|
||||||
if (this._eventQueue) {
|
if (this._eventQueue) {
|
||||||
this._eventQueue.push(new AddEvent(index, value));
|
this._eventQueue.push(new AddEvent(index, value));
|
||||||
this._flush();
|
this._flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onUpdate(index, value, params) {
|
onUpdate(index: number, value: F, params: any): void {
|
||||||
if (this._eventQueue) {
|
if (this._eventQueue) {
|
||||||
this._eventQueue.push(new UpdateEvent(index, value, params));
|
this._eventQueue.push(new UpdateEvent(index, value, params));
|
||||||
this._flush();
|
this._flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onRemove(index) {
|
onRemove(index: number): void {
|
||||||
if (this._eventQueue) {
|
if (this._eventQueue) {
|
||||||
this._eventQueue.push(new RemoveEvent(index));
|
this._eventQueue.push(new RemoveEvent(index));
|
||||||
this._flush();
|
this._flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMove(fromIdx, toIdx) {
|
onMove(fromIdx: number, toIdx: number): void {
|
||||||
if (this._eventQueue) {
|
if (this._eventQueue) {
|
||||||
this._eventQueue.push(new MoveEvent(fromIdx, toIdx));
|
this._eventQueue.push(new MoveEvent(fromIdx, toIdx));
|
||||||
this._flush();
|
this._flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onUnsubscribeLast() {
|
onUnsubscribeLast(): void {
|
||||||
this._sourceUnsubscribe();
|
this._sourceUnsubscribe!();
|
||||||
this._eventQueue = null;
|
this._eventQueue = null;
|
||||||
this._mappedValues = null;
|
this._mappedValues = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AddEvent {
|
type AsyncEvent<F> = AddEvent<F> | UpdateEvent<F> | RemoveEvent<F> | MoveEvent<F> | ResetEvent<F>
|
||||||
constructor(index, value) {
|
|
||||||
this.index = index;
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
async run(list) {
|
class AddEvent<F> {
|
||||||
|
constructor(public index: number, public value: F) {}
|
||||||
|
|
||||||
|
async run<T>(list: AsyncMappedList<F,T>): Promise<void> {
|
||||||
const mappedValue = await list._mapper(this.value);
|
const mappedValue = await list._mapper(this.value);
|
||||||
runAdd(list, this.index, mappedValue);
|
runAdd(list, this.index, mappedValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class UpdateEvent {
|
class UpdateEvent<F> {
|
||||||
constructor(index, value, params) {
|
constructor(public index: number, public value: F, public params: any) {}
|
||||||
this.index = index;
|
|
||||||
this.value = value;
|
|
||||||
this.params = params;
|
|
||||||
}
|
|
||||||
|
|
||||||
async run(list) {
|
async run<T>(list: AsyncMappedList<F,T>): Promise<void> {
|
||||||
runUpdate(list, this.index, this.value, this.params);
|
runUpdate(list, this.index, this.value, this.params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RemoveEvent {
|
class RemoveEvent<F> {
|
||||||
constructor(index) {
|
constructor(public index: number) {}
|
||||||
this.index = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
async run(list) {
|
async run<T>(list: AsyncMappedList<F,T>): Promise<void> {
|
||||||
runRemove(list, this.index);
|
runRemove(list, this.index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MoveEvent {
|
class MoveEvent<F> {
|
||||||
constructor(fromIdx, toIdx) {
|
constructor(public fromIdx: number, public toIdx: number) {}
|
||||||
this.fromIdx = fromIdx;
|
|
||||||
this.toIdx = toIdx;
|
|
||||||
}
|
|
||||||
|
|
||||||
async run(list) {
|
async run<T>(list: AsyncMappedList<F,T>): Promise<void> {
|
||||||
runMove(list, this.fromIdx, this.toIdx);
|
runMove(list, this.fromIdx, this.toIdx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ResetEvent {
|
class ResetEvent<F> {
|
||||||
async run(list) {
|
async run<T>(list: AsyncMappedList<F,T>): Promise<void> {
|
||||||
runReset(list);
|
runReset(list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,7 +139,7 @@ export function tests() {
|
||||||
return {
|
return {
|
||||||
"events are emitted in order": async assert => {
|
"events are emitted in order": async assert => {
|
||||||
const double = n => n * n;
|
const double = n => n * n;
|
||||||
const source = new ObservableArray();
|
const source = new ObservableArray<number>();
|
||||||
const mapper = new AsyncMappedList(source, async n => {
|
const mapper = new AsyncMappedList(source, async n => {
|
||||||
await new Promise(r => setTimeout(r, n));
|
await new Promise(r => setTimeout(r, n));
|
||||||
return {n: double(n)};
|
return {n: double(n)};
|
||||||
|
|
Reference in a new issue