Elysia Tools

Просматривайте инструменты, примеры, визуальные объяснения и тематические руководства в одном понятном пространстве.

Популярные категории

Темы

Язык
ZHESPTRUFRDEEN

Elysia Tools

Навигация

TypeScript

Примеры Многопоточности Web TypeScript

Примеры многопоточности Web TypeScript включая Web Workers, асинхронные операции и параллельную обработку

Примеры

Элементы этой коллекции

КодtypescriptСредний

Web Workers

Создание и использование Web Workers для параллельного выполнения в браузере

Сложность

6/10

Оценка времени

30 min

Теги

typescript, web, multithreading

Предварительные условия

Intermediate TypeScript, Web Workers API

typescript
// Web TypeScript Web Workers Examples
// Using Web Workers for parallel execution and background processing

// 1. Basic Web Worker Creation
class WorkerManager {
  private workers: Map<string, Worker> = new Map();

  // Create inline worker from code
  createInlineWorker(name: string, workerCode: string): Worker {
    const blob = new Blob([workerCode], { type: 'application/javascript' });
    const workerUrl = URL.createObjectURL(blob);
    const worker = new Worker(workerUrl);

    this.workers.set(name, worker);
    return worker;
  }

  // Create worker from external file
  createWorker(name: string, workerFile: string): Worker {
    const worker = new Worker(workerFile);
    this.workers.set(name, worker);
    return worker;
  }

  // Get worker by name
  getWorker(name: string): Worker | undefined {
    return this.workers.get(name);
  }

  // Terminate worker
  terminateWorker(name: string): void {
    const worker = this.workers.get(name);
    if (worker) {
      worker.terminate();
      this.workers.delete(name);
    }
  }

  // Terminate all workers
  terminateAllWorkers(): void {
    for (const [name, worker] of this.workers) {
      worker.terminate();
    }
    this.workers.clear();
  }
}

// 2. Worker Communication
class WorkerCommunication {
  private worker: Worker;

  constructor(worker: Worker) {
    this.worker = worker;
  }

  // Send message to worker
  postMessage(message: any, transfer?: Transferable[]): void {
    this.worker.postMessage(message, transfer);
  }

  // Set onmessage handler
  onMessage(handler: (message: MessageEvent) => void): void {
    this.worker.onmessage = handler;
  }

  // Set onerror handler
  onError(handler: (error: ErrorEvent) => void): void {
    this.worker.onerror = handler;
  }

  // Send message and wait for response
  async sendMessage(message: any): Promise<any> {
    return new Promise((resolve, reject) => {
      const handleMessage = (e: MessageEvent) => {
        this.worker.removeEventListener('message', handleMessage);
        resolve(e.data);
      };

      const handleError = (e: ErrorEvent) => {
        this.worker.removeEventListener('error', handleError);
        reject(e.error);
      };

      this.worker.addEventListener('message', handleMessage);
      this.worker.addEventListener('error', handleError);

      this.worker.postMessage(message);
    });
  }
}

// 3. Worker Task Executor
class WorkerTaskExecutor {
  private workerManager: WorkerManager;

  constructor() {
    this.workerManager = new WorkerManager();
  }

  // Execute computation in worker
  async executeComputation(input: any): Promise<any> {
    const workerCode = `
      self.onmessage = function(e) {
        const input = e.data;
        const result = performComputation(input);
        self.postMessage(result);
      };

      function performComputation(input) {
        // Perform computation here
        return { result: input.value * 2 };
      }
    `;

    const worker = this.workerManager.createInlineWorker('computation', workerCode);
    const comm = new WorkerCommunication(worker);

    const result = await comm.sendMessage(input);
    this.workerManager.terminateWorker('computation');

    return result;
  }

  // Execute parallel computations
  async executeParallel(inputs: any[], workerCode: string): Promise<any[]> {
    const workers: Worker[] = [];
    const promises: Promise<any>[] = [];

    for (const input of inputs) {
      const worker = this.workerManager.createInlineWorker(`worker-${inputs.indexOf(input)}`, workerCode);
      workers.push(worker);

      const comm = new WorkerCommunication(worker);
      promises.push(comm.sendMessage(input));
    }

    const results = await Promise.all(promises);

    // Clean up workers
    workers.forEach(worker => worker.terminate());

    return results;
  }
}

// 4. Worker Pool
class WorkerPool {
  private workers: Worker[] = [];
  private taskQueue: Array<{ task: any; resolve: (value: any) => void; reject: (reason: any) => void }> = [];
  private availableWorkers: Worker[] = [];
  private inFlightTasks: Map<Worker, { task: any; resolve: (value: any) => void; reject: (reason: any) => void }> = new Map();

  constructor(workerCode: string, poolSize: number) {
    // Create workers
    for (let i = 0; i < poolSize; i++) {
      const blob = new Blob([workerCode], { type: 'application/javascript' });
      const workerUrl = URL.createObjectURL(blob);
      const worker = new Worker(workerUrl);

      worker.onmessage = (e) => {
        const task = this.inFlightTasks.get(worker);
        if (task) {
          task.resolve(e.data);
          this.inFlightTasks.delete(worker);
          this.releaseWorker(worker);
        }
      };

      worker.onerror = (e) => {
        const task = this.inFlightTasks.get(worker);
        if (task) {
          task.reject(e.error);
          this.inFlightTasks.delete(worker);
          this.releaseWorker(worker);
        }
      };

      this.workers.push(worker);
      this.availableWorkers.push(worker);
    }
  }

  // Execute task
  async execute(task: any): Promise<any> {
    return new Promise((resolve, reject) => {
      this.taskQueue.push({ task, resolve, reject });
      this.processQueue();
    });
  }

  private processQueue(): void {
    if (this.taskQueue.length === 0 || this.availableWorkers.length === 0) {
      return;
    }

    const taskItem = this.taskQueue.shift();
    const worker = this.availableWorkers.shift()!;

    this.inFlightTasks.set(worker, taskItem);
    worker.postMessage(taskItem.task);
  }

  private releaseWorker(worker: Worker): void {
    this.availableWorkers.push(worker);
    this.processQueue();
  }

  // Terminate all workers
  terminate(): void {
    this.workers.forEach(worker => worker.terminate());
    this.workers = [];
    this.availableWorkers = [];
    this.taskQueue = [];
    this.inFlightTasks.clear();
  }
}

// 5. Shared Worker
class SharedWorkerManager {
  private sharedWorker: SharedWorker | null = null;

  // Create shared worker
  createSharedWorker(name: string, workerCode: string): SharedWorker {
    const blob = new Blob([workerCode], { type: 'application/javascript' });
    const workerUrl = URL.createObjectURL(blob);
    this.sharedWorker = new SharedWorker(workerUrl, name);
    return this.sharedWorker;
  }

  // Connect to shared worker port
  connect(): MessagePort {
    if (!this.sharedWorker) {
      throw new Error('Shared worker not created');
    }

    return this.sharedWorker.port;
  }

  // Start connection
  start(): void {
    const port = this.connect();
    port.start();
  }

  // Post message to shared worker
  postMessage(message: any): void {
    const port = this.connect();
    port.postMessage(message);
  }

  // Set message handler
  onMessage(handler: (message: MessageEvent) => void): void {
    const port = this.connect();
    port.onmessage = handler;
  }
}

// 6. Worker with Progress Tracking
class WorkerWithProgress {
  private worker: Worker;
  private communication: WorkerCommunication;

  constructor(workerCode: string) {
    const blob = new Blob([workerCode], { type: 'application/javascript' });
    const workerUrl = URL.createObjectURL(blob);
    this.worker = new Worker(workerUrl);
    this.communication = new WorkerCommunication(this.worker);
  }

  // Execute task with progress callback
  async executeWithProgress(
    task: any,
    onProgress: (progress: number) => void
  ): Promise<any> {
    return new Promise((resolve, reject) => {
      this.communication.onMessage = (e: MessageEvent) => {
        const data = e.data;

        if (data.type === 'progress') {
          onProgress(data.value);
        } else if (data.type === 'complete') {
          resolve(data.result);
        } else if (data.type === 'error') {
          reject(new Error(data.message));
        }
      };

      this.communication.onError = (e: ErrorEvent) => {
        reject(e.error);
      };

      this.communication.postMessage(task);
    });
  }

  // Terminate worker
  terminate(): void {
    this.worker.terminate();
  }
}

// 7. Batch Processing with Workers
class BatchWorkerProcessor {
  private workerManager = new WorkerManager();

  // Process batch of items
  async processBatch<T, R>(
    items: T[],
    processorCode: string,
    batchSize: number = 10,
    onProgress?: (current: number, total: number) => void
  ): Promise<R[]> {
    const results: R[] = [];
    const batches: T[][] = [];

    // Split into batches
    for (let i = 0; i < items.length; i += batchSize) {
      batches.push(items.slice(i, i + batchSize));
    }

    // Process each batch
    for (let i = 0; i < batches.length; i++) {
      const batch = batches[i];
      const batchResults = await this.processBatchImpl(batch, processorCode);
      results.push(...batchResults);

      if (onProgress) {
        onProgress(Math.min((i + 1) * batchSize, items.length), items.length);
      }
    }

    return results;
  }

  private async processBatchImpl<T, R>(batch: T[], processorCode: string): Promise<R[]> {
    const workerCode = `
      ${processorCode}

      self.onmessage = function(e) {
        const batch = e.data;
        const results = batch.map(processItem);
        self.postMessage(results);
      };
    `;

    const worker = this.workerManager.createInlineWorker('batch', workerCode);
    const comm = new WorkerCommunication(worker);

    const results = await comm.sendMessage(batch);
    this.workerManager.terminateWorker('batch');

    return results;
  }
}

// 8. Worker Utilities
class WorkerUtils {
  // Check if Web Workers are supported
  static isSupported(): boolean {
    return typeof Worker !== 'undefined';
  }

  // Check if Shared Workers are supported
  static isSharedWorkerSupported(): boolean {
    return typeof SharedWorker !== 'undefined';
  }

  // Create worker from function
  static createWorkerFromFunction(fn: Function): Worker {
    const fnString = fn.toString();
    const workerCode = `
      const workerFunction = ${fnString};
      self.onmessage = (e) => {
        const result = workerFunction(e.data);
        self.postMessage(result);
      };
    `;

    const blob = new Blob([workerCode], { type: 'application/javascript' });
    const workerUrl = URL.createObjectURL(blob);
    return new Worker(workerUrl);
  }

  // Execute function in worker
  static async executeInWorker<T, R>(fn: (input: T) => R, input: T): Promise<R> {
    const worker = this.createWorkerFromFunction(fn);

    return new Promise((resolve, reject) => {
      worker.onmessage = (e) => {
        resolve(e.data as R);
        worker.terminate();
      };

      worker.onerror = (e) => {
        reject(e.error);
        worker.terminate();
      };

      worker.postMessage(input);
    });
  }
}

// Usage Examples
async function demonstrateWebWorkers() {
  console.log('=== Web TypeScript Web Workers Examples ===\n');

  // Check support
  console.log('--- Web Workers Support ---');
  console.log(`Web Workers supported: ${WorkerUtils.isSupported()}`);
  console.log(`Shared Workers supported: ${WorkerUtils.isSharedWorkerSupported()}`);

  // 1. Basic worker
  console.log('\n--- 1. Basic Web Worker ---');
  const workerManager = new WorkerManager();

  const basicWorkerCode = `
    self.onmessage = function(e) {
      const data = e.data;
      console.log('Worker received:', data);
      const result = data.value * 2;
      self.postMessage({ result: result });
    };
  `;

  const worker = workerManager.createInlineWorker('basic', basicWorkerCode);
  const comm = new WorkerCommunication(worker);

  comm.onMessage = (e) => {
    console.log(`Worker response: ${JSON.stringify(e.data)}`);
  };

  comm.postMessage({ value: 21 });

  // Wait for response
  await new Promise(resolve => setTimeout(resolve, 100));
  workerManager.terminateWorker('basic');

  // 2. Execute computation in worker
  console.log('\n--- 2. Execute Computation ---');
  const executor = new WorkerTaskExecutor();

  const computationResult = await executor.executeComputation({ value: 10 });
  console.log(`Computation result: ${JSON.stringify(computationResult)}`);

  // 3. Parallel execution
  console.log('\n--- 3. Parallel Execution ---');
  const parallelWorkerCode = `
    self.onmessage = function(e) {
      const input = e.data;
      const result = input * input; // Square the input
      self.postMessage(result);
    };
  `;

  const inputs = [1, 2, 3, 4, 5];
  const parallelResults = await executor.executeParallel(inputs, parallelWorkerCode);
  console.log(`Parallel results: ${parallelResults.join(', ')}`);

  // 4. Worker with progress
  console.log('\n--- 4. Worker with Progress ---');
  const progressWorkerCode = `
    self.onmessage = function(e) {
      const task = e.data;

      // Simulate progress
      for (let i = 0; i <= 100; i += 10) {
        self.postMessage({ type: 'progress', value: i });
      }

      self.postMessage({ type: 'complete', result: task.input * 2 });
    };
  `;

  const progressWorker = new WorkerWithProgress(progressWorkerCode);
  const progressResult = await progressWorker.executeWithProgress(
    { input: 15 },
    (progress) => console.log(`Progress: ${progress}%`)
  );
  console.log(`Result with progress: ${progressResult.result}`);
  progressWorker.terminate();

  // 5. Batch processing
  console.log('\n--- 5. Batch Processing ---');
  const batchProcessor = new BatchWorkerProcessor();

  const processorCode = `
    function processItem(item) {
      return item * item;
    }
  `;

  const items = Array.from({ length: 25 }, (_, i) => i + 1);
  const batchResults = await batchProcessor.processBatch(
    items,
    processorCode,
    5,
    (current, total) => console.log(`Batch progress: ${current}/${total}`)
  );

  console.log(`Batch results (first 10): ${batchResults.slice(0, 10).join(', ')}...`);

  // 6. Execute function in worker
  console.log('\n--- 6. Execute Function in Worker ---');
  const squareResult = await WorkerUtils.executeInWorker(
    (x: number) => x * x,
    7
  );
  console.log(`Square result: ${squareResult}`);

  // 7. Heavy computation
  console.log('\n--- 7. Heavy Computation ---');
  const heavyWorkerCode = `
    self.onmessage = function(e) {
      const n = e.data.n;
      let sum = 0;

      for (let i = 1; i <= n; i++) {
        sum += i;
      }

      self.postMessage({ sum: sum });
    };
  `;

  const heavyWorker = workerManager.createInlineWorker('heavy', heavyWorkerCode);
  const heavyComm = new WorkerCommunication(heavyWorker);

  const heavyResult = await heavyComm.sendMessage({ n: 1000000 });
  console.log(`Heavy computation result: Sum from 1 to 1000000 = ${heavyResult.sum}`);

  workerManager.terminateWorker('heavy');

  console.log('\n=== All Web Workers Examples Completed ===');
}

// Export classes
export { WorkerManager, WorkerCommunication, WorkerTaskExecutor, WorkerPool, SharedWorkerManager, WorkerWithProgress, BatchWorkerProcessor, WorkerUtils };
export { demonstrateWebWorkers };
КодtypescriptСредний

Асинхронные Операции

Мастерство async/await паттернов, Promises и параллельного выполнения в TypeScript

Сложность

5/10

Оценка времени

25 min

Теги

typescript, web, multithreading, async

Предварительные условия

Intermediate TypeScript, Async/Await

typescript
// Web TypeScript Async/Await Operations Examples
// Mastering Promises, async/await, and concurrent execution patterns

// 1. Promise Basics
class PromiseBasics {
  // Create a resolving promise
  static resolve<T>(value: T): Promise<T> {
    return Promise.resolve(value);
  }

  // Create a rejecting promise
  static reject<T>(error: T): Promise<never> {
    return Promise.reject(error);
  }

  // Create promise from callback
  static fromCallback<T>(
    callback: (cb: (error: Error | null, result: T) => void) => void
  ): Promise<T> {
    return new Promise((resolve, reject) => {
      callback((error, result) => {
        if (error) {
          reject(error);
        } else {
          resolve(result);
        }
      });
    });
  }

  // Delay execution
  static delay(ms: number): Promise<void> {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

  // Timeout a promise
  static withTimeout<T>(promise: Promise<T>, timeoutMs: number, errorMessage: string = 'Timeout'): Promise<T> {
    return Promise.race([
      promise,
      PromiseBasics.delay(timeoutMs).then(() => {
        throw new Error(errorMessage);
      })
    ]);
  }

  // Retry promise
  static async retry<T>(
    fn: () => Promise<T>,
    maxAttempts: number = 3,
    delayMs: number = 1000
  ): Promise<T> {
    let lastError: Error;

    for (let attempt = 1; attempt <= maxAttempts; attempt++) {
      try {
        return await fn();
      } catch (error) {
        lastError = error as Error;
        if (attempt < maxAttempts) {
          await this.delay(delayMs * attempt);
        }
      }
    }

    throw lastError!;
  }
}

// 2. Async Control Flow
class AsyncControlFlow {
  // Execute sequentially
  static async sequential<T>(tasks: Array<() => Promise<T>>): Promise<T[]> {
    const results: T[] = [];

    for (const task of tasks) {
      const result = await task();
      results.push(result);
    }

    return results;
  }

  // Execute parallel with limit
  static async parallelWithLimit<T>(
    tasks: Array<() => Promise<T>>,
    limit: number
  ): Promise<T[]> {
    const results: T[] = [];
    const executing: Promise<void>[] = [];

    for (const task of tasks) {
      const promise = task().then(result => {
        results.push(result);
      });

      executing.push(promise);

      if (executing.length >= limit) {
        await Promise.race(executing);
        executing.splice(executing.findIndex(p => p === promise), 1);
      }
    }

    await Promise.all(executing);
    return results;
  }

  // Execute parallel with batching
  static async batchParallel<T>(
    items: T[],
    processor: (item: T) => Promise<any>,
    batchSize: number
  ): Promise<any[]> {
    const results: any[] = [];

    for (let i = 0; i < items.length; i += batchSize) {
      const batch = items.slice(i, i + batchSize);
      const batchResults = await Promise.all(batch.map(processor));
      results.push(...batchResults);
    }

    return results;
  }

  // Execute with fallback
  static async withFallback<T>(
    primary: () => Promise<T>,
    fallback: () => Promise<T>
  ): Promise<T> {
    try {
      return await primary();
    } catch {
      return await fallback();
    }
  }

  // Execute with circuit breaker
  static withCircuitBreaker<T>(
    fn: () => Promise<T>,
    options: {
      timeout?: number;
      maxFailures?: number;
      resetTimeout?: number;
    } = {}
  ): () => Promise<T> {
    let failures = 0;
    let lastFailureTime = 0;
    let circuitOpen = false;

    const {
      timeout = 5000,
      maxFailures = 5,
      resetTimeout = 60000
    } = options;

    return async () => {
      if (circuitOpen) {
        if (Date.now() - lastFailureTime > resetTimeout) {
          circuitOpen = false;
          failures = 0;
        } else {
          throw new Error('Circuit breaker is open');
        }
      }

      try {
        const result = await PromiseBasics.withTimeout(fn(), timeout);
        failures = 0;
        return result;
      } catch (error) {
        failures++;
        lastFailureTime = Date.now();

        if (failures >= maxFailures) {
          circuitOpen = true;
        }

        throw error;
      }
    };
  }
}

// 3. Async Utilities
class AsyncUtilities {
  // Map array asynchronously
  static async map<T, R>(
    array: T[],
    mapper: (item: T, index: number) => Promise<R>
  ): Promise<R[]> {
    const promises = array.map((item, index) => mapper(item, index));
    return Promise.all(promises);
  }

  // Filter array asynchronously
  static async filter<T>(
    array: T[],
    predicate: (item: T, index: number) => Promise<boolean>
  ): Promise<T[]> {
    const results = await Promise.all(
      array.map(async (item, index) => ({
        item,
        keep: await predicate(item, index)
      }))
    );

    return results.filter(result => result.keep).map(result => result.item);
  }

  // Reduce array asynchronously
  static async reduce<T, R>(
    array: T[],
    reducer: (accumulator: R, item: T, index: number) => Promise<R>,
    initialValue: R
  ): Promise<R> {
    let accumulator = initialValue;

    for (let i = 0; i < array.length; i++) {
      accumulator = await reducer(accumulator, array[i], i);
    }

    return accumulator;
  }

  // Find asynchronously
  static async find<T>(
    array: T[],
    predicate: (item: T) => Promise<boolean>
  ): Promise<T | undefined> {
    for (const item of array) {
      if (await predicate(item)) {
        return item;
      }
    }
    return undefined;
  }

  // Some asynchronously
  static async some<T>(
    array: T[],
    predicate: (item: T) => Promise<boolean>
  ): Promise<boolean> {
    for (const item of array) {
      if (await predicate(item)) {
        return true;
      }
    }
    return false;
  }

  // Every asynchronously
  static async every<T>(
    array: T[],
    predicate: (item: T) => Promise<boolean>
  ): Promise<boolean> {
    for (const item of array) {
      if (!(await predicate(item))) {
        return false;
      }
    }
    return true;
  }
}

// 4. Async Queue
class AsyncQueue<T> {
  private queue: T[] = [];
  private pendingWaiters: Array<(value: T) => void> = [];

  // Enqueue item
  enqueue(item: T): void {
    if (this.pendingWaiters.length > 0) {
      const waiter = this.pendingWaiters.shift()!;
      waiter(item);
    } else {
      this.queue.push(item);
    }
  }

  // Dequeue item
  async dequeue(): Promise<T> {
    if (this.queue.length > 0) {
      return this.queue.shift()!;
    }

    return new Promise(resolve => {
      this.pendingWaiters.push(resolve);
    });
  }

  // Get size
  get size(): number {
    return this.queue.length;
  }
}

// 5. Async Mutex
class AsyncMutex {
  private locked = false;
  private waiters: Array<() => void> = [];

  // Acquire lock
  async acquire(): Promise<void> {
    if (!this.locked) {
      this.locked = true;
      return;
    }

    return new Promise(resolve => {
      this.waiters.push(resolve);
    });
  }

  // Release lock
  release(): void {
    if (this.waiters.length > 0) {
      const waiter = this.waiters.shift()!;
      waiter();
    } else {
      this.locked = false;
    }
  }

  // Execute critical section
  async execute<T>(fn: () => Promise<T>): Promise<T> {
    await this.acquire();
    try {
      return await fn();
    } finally {
      this.release();
    }
  }
}

// 6. Async Semaphore
class AsyncSemaphore {
  private permits: number;
  private waiters: Array<() => void> = [];

  constructor(permits: number) {
    this.permits = permits;
  }

  // Acquire permit
  async acquire(): Promise<void> {
    if (this.permits > 0) {
      this.permits--;
      return;
    }

    return new Promise(resolve => {
      this.waiters.push(resolve);
    });
  }

  // Release permit
  release(): void {
    if (this.waiters.length > 0) {
      const waiter = this.waiters.shift()!;
      waiter();
    } else {
      this.permits++;
    }
  }

  // Execute with semaphore
  async execute<T>(fn: () => Promise<T>): Promise<T> {
    await this.acquire();
    try {
      return await fn();
    } finally {
      this.release();
    }
  }
}

// 7. Async Cache
class AsyncCache<K, V> {
  private cache = new Map<K, V>();
  private pending = new Map<K, Promise<V>>();

  // Get or compute value
  async getOrCompute(key: K, compute: () => Promise<V>): Promise<V> {
    // Check cache
    if (this.cache.has(key)) {
      return this.cache.get(key)!;
    }

    // Check pending computation
    if (this.pending.has(key)) {
      return this.pending.get(key)!;
    }

    // Compute new value
    const promise = compute().then(value => {
      this.cache.set(key, value);
      this.pending.delete(key);
      return value;
    });

    this.pending.set(key, promise);
    return promise;
  }

  // Get value
  get(key: K): V | undefined {
    return this.cache.get(key);
  }

  // Set value
  set(key: K, value: V): void {
    this.cache.set(key, value);
  }

  // Clear cache
  clear(): void {
    this.cache.clear();
    this.pending.clear();
  }

  // Get size
  get size(): number {
    return this.cache.size;
  }
}

// 8. Async Rate Limiter
class AsyncRateLimiter {
  private queue: Array<() => void> = [];
  private running = 0;
  private interval: number;

  constructor(concurrency: number, intervalMs: number) {
    this.interval = intervalMs;
    this.running = concurrency;

    // Start ticker
    setInterval(() => {
      if (this.queue.length > 0 && this.running < concurrency) {
        const task = this.queue.shift()!;
        task();
        this.running--;
      }
    }, intervalMs);
  }

  // Execute with rate limiting
  async execute<T>(fn: () => Promise<T>): Promise<T> {
    return new Promise((resolve, reject) => {
      const task = async () => {
        try {
          const result = await fn();
          resolve(result);
        } catch (error) {
          reject(error);
        }
      };

      if (this.running > 0) {
        this.running--;
        task();
      } else {
        this.queue.push(task);
      }
    });
  }
}

// Usage Examples
async function demonstrateAsyncOperations() {
  console.log('=== Web TypeScript Async/Await Operations Examples ===\n');

  // 1. Promise basics
  console.log('--- 1. Promise Basics ---');
  const resolved = await PromiseBasics.resolve(42);
  console.log(`Resolved: ${resolved}`);

  try {
    await PromiseBasics.reject(new Error('Test error'));
  } catch (error) {
    console.log(`Rejected: ${(error as Error).message}`);
  }

  await PromiseBasics.delay(100);
  console.log('Delay completed');

  // 2. Sequential vs parallel
  console.log('\n--- 2. Sequential vs Parallel ---');

  const tasks = [
    () => PromiseBasics.delay(100).then(() => 1),
    () => PromiseBasics.delay(200).then(() => 2),
    () => PromiseBasics.delay(150).then(() => 3)
  ];

  const startTime = Date.now();
  const sequentialResults = await AsyncControlFlow.sequential(tasks);
  console.log(`Sequential: ${sequentialResults.join(', ')} (${Date.now() - startTime}ms)`);

  const parallelResults = await Promise.all(tasks.map(t => t()));
  console.log(`Parallel: ${parallelResults.join(', ')} (${Date.now() - startTime}ms)`);

  // 3. Parallel with limit
  console.log('\n--- 3. Parallel with Limit ---');
  const limitStartTime = Date.now();
  const limitedResults = await AsyncControlFlow.parallelWithLimit(tasks, 2);
  console.log(`Limited (2): ${limitedResults.join(', ')} (${Date.now() - limitStartTime}ms)`);

  // 4. Async map
  console.log('\n--- 4. Async Map ---');
  const numbers = [1, 2, 3, 4, 5];
  const doubled = await AsyncUtilities.map(numbers, async (n) => {
    await PromiseBasics.delay(50);
    return n * 2;
  });
  console.log(`Doubled: ${doubled.join(', ')}`);

  // 5. Async filter
  console.log('\n--- 5. Async Filter ---');
  const evens = await AsyncUtilities.filter(numbers, async (n) => {
    await PromiseBasics.delay(10);
    return n % 2 === 0;
  });
  console.log(`Even numbers: ${evens.join(', ')}`);

  // 6. Async queue
  console.log('\n--- 6. Async Queue ---');
  const queue = new AsyncQueue<number>();

  queue.enqueue(1);
  queue.enqueue(2);
  queue.enqueue(3);

  console.log(`Queue size: ${queue.size}`);
  console.log(`Dequeue: ${await queue.dequeue()}`);
  console.log(`Dequeue: ${await queue.dequeue()}`);

  // 7. Async mutex
  console.log('\n--- 7. Async Mutex ---');
  const mutex = new AsyncMutex();

  const mutexTask = mutex.execute(async () => {
    console.log('Critical section start');
    await PromiseBasics.delay(100);
    console.log('Critical section end');
    return 'done';
  });

  console.log(`Mutex result: ${await mutexTask}`);

  // 8. Async cache
  console.log('\n--- 8. Async Cache ---');
  const cache = new AsyncCache<string, string>();

  const computeResult1 = await cache.getOrCompute('key1', async () => {
    console.log('Computing value for key1');
    await PromiseBasics.delay(100);
    return 'value1';
  });

  const computeResult2 = await cache.getOrCompute('key1', async () => {
    console.log('This should not print');
    return 'value1-different';
  });

  console.log(`Cache results: ${computeResult1}, ${computeResult2}`);
  console.log(`Cache size: ${cache.size}`);

  // 9. Retry
  console.log('\n--- 9. Retry ---');
  let attempts = 0;
  const retryResult = await PromiseBasics.retry(async () => {
    attempts++;
    console.log(`Attempt ${attempts}`);
    if (attempts < 3) {
      throw new Error('Not yet');
    }
    return 'success';
  }, 5, 50);

  console.log(`Retry result: ${retryResult}`);

  // 10. Timeout
  console.log('\n--- 10. Timeout ---');
  try {
    await PromiseBasics.withTimeout(
      PromiseBasics.delay(2000).then(() => 'slow'),
      100,
      'Too slow'
    );
  } catch (error) {
    console.log(`Timeout error: ${(error as Error).message}`);
  }

  console.log('\n=== All Async/Await Examples Completed ===');
}

// Export classes
export { PromiseBasics, AsyncControlFlow, AsyncUtilities, AsyncQueue, AsyncMutex, AsyncSemaphore, AsyncCache, AsyncRateLimiter };
export { demonstrateAsyncOperations };
КодtypescriptСложный

Примитивы Синхронизации

Реализация синхронизации используя Atomics, SharedArrayBuffer и блокировки

Сложность

8/10

Оценка времени

40 min

Теги

typescript, web, multithreading, synchronization

Предварительные условия

Advanced TypeScript, Atomics API, SharedArrayBuffer

typescript
// Web TypeScript Synchronization Primitives Examples
// Using Atomics, SharedArrayBuffer, and custom synchronization

// 1. Atomics Operations
class AtomicsOperations {
  // Create shared buffer
  static createSharedBuffer(size: number): Int32Array {
    const buffer = new SharedArrayBuffer(size * Int32Array.BYTES_PER_ELEMENT);
    return new Int32Array(buffer);
  }

  // Compare and swap
  static compareAndSwap(
    array: Int32Array,
    index: number,
    expectedValue: number,
    newValue: number
  ): boolean {
    return Atomics.compareExchange(array, index, expectedValue, newValue) === expectedValue;
  }

  // Add atomically
  static add(array: Int32Array, index: number, value: number): number {
    return Atomics.add(array, index, value);
  }

  // Sub atomically
  static sub(array: Int32Array, index: number, value: number): number {
    return Atomics.sub(array, index, value);
  }

  // Increment atomically
  static increment(array: Int32Array, index: number): number {
    return Atomics.add(array, index, 1);
  }

  // Decrement atomically
  static decrement(array: Int32Array, index: number): number {
    return Atomics.sub(array, index, 1);
  }

  // Load atomically
  static load(array: Int32Array, index: number): number {
    return Atomics.load(array, index);
  }

  // Store atomically
  static store(array: Int32Array, index: number, value: number): void {
    Atomics.store(array, index, value);
  }

  // Wait for notification
  static waitAsync(array: Int32Array, index: number, expectedValue: number, timeout?: number): Promise<'ok' | 'not-equal' | 'timed-out'> {
    return Atomics.waitAsync(array, index, expectedValue, timeout).then(() => 'ok');
  }

  // Notify waiters
  static notify(array: Int32Array, index: number, count: number): number {
    return Atomics.notify(array, index, count);
  }
}

// 2. Spinlock
class Spinlock {
  private locked: Int32Array;

  constructor() {
    this.locked = AtomicsOperations.createSharedBuffer(1);
  }

  // Acquire lock (busy-wait)
  acquire(): void {
    while (true) {
      // Try to acquire lock
      const previous = AtomicsOperations.exchange(this.locked, 0, 1);

      if (previous === 0) {
        // Lock acquired
        return;
      }

      // Wait for notification
      Atomics.wait(this.locked, 0, 1);
    }
  }

  // Release lock
  release(): void {
    AtomicsOperations.store(this.locked, 0, 0);
    AtomicsOperations.notify(this.locked, 0, 1);
  }
}

// 3. Mutex (Better than Spinlock)
class Mutex {
  private locked: Int32Array;

  constructor() {
    this.locked = AtomicsOperations.createSharedBuffer(1);
  }

  // Acquire lock with timeout
  async acquire(timeoutMs: number = 5000): Promise<boolean> {
    const start = Date.now();

    while (true) {
      // Try to acquire lock
      const previous = AtomicsOperations.compareAndSwap(this.locked, 0, 0, 1);

      if (previous === 0) {
        return true;
      }

      // Check timeout
      if (Date.now() - start > timeoutMs) {
        return false;
      }

      // Wait with timeout
      await AtomicsOperations.waitAsync(this.locked, 0, 1, 100);
    }
  }

  // Release lock
  release(): void {
    AtomicsOperations.store(this.locked, 0, 0);
    AtomicsOperations.notify(this.locked, 0, 1);
  }

  // Execute critical section
  async execute<T>(fn: () => Promise<T>, timeoutMs?: number): Promise<T> {
    const acquired = await this.acquire(timeoutMs);

    if (!acquired) {
      throw new Error('Mutex acquisition timeout');
    }

    try {
      return await fn();
    } finally {
      this.release();
    }
  }
}

// 4. Semaphore
class Semaphore {
  private permits: Int32Array;

  constructor(initialPermits: number) {
    this.permits = AtomicsOperations.createSharedBuffer(1);
    AtomicsOperations.store(this.permits, 0, initialPermits);
  }

  // Acquire permit
  async acquire(timeoutMs: number = 5000): Promise<boolean> {
    const start = Date.now();

    while (true) {
      const current = AtomicsOperations.load(this.permits, 0);

      if (current > 0) {
        // Try to acquire permit
        const previous = AtomicsOperations.compareAndSwap(
          this.permits,
          0,
          current,
          current - 1
        );

        if (previous === current) {
          return true;
        }
      }

      // Check timeout
      if (Date.now() - start > timeoutMs) {
        return false;
      }

      // Wait
      await AtomicsOperations.waitAsync(this.permits, 0, current, 100);
    }
  }

  // Release permit
  release(): void {
    AtomicsOperations.increment(this.permits, 0);
    AtomicsOperations.notify(this.permits, 0, 1);
  }

  // Execute with semaphore
  async execute<T>(fn: () => Promise<T>): Promise<T> {
    await this.acquire();
    try {
      return await fn();
    } finally {
      this.release();
    }
  }
}

// 5. Barrier
class Barrier {
  private count: Int32Array;
  private waiting: Int32Array;
  private total: number;

  constructor(parties: number) {
    this.total = parties;
    this.count = AtomicsOperations.createSharedBuffer(1);
    this.waiting = AtomicsOperations.createSharedBuffer(1);
  }

  // Wait for all parties
  async wait(): Promise<void> {
    const index = AtomicsOperations.add(this.waiting, 0, 1);

    if (index === this.total) {
      // Last party resets the barrier
      AtomicsOperations.store(this.waiting, 0, 0);
      AtomicsOperations.store(this.count, 0, 0);
      AtomicsOperations.notify(this.count, 0, this.total);
    } else {
      // Wait for last party
      await AtomicsOperations.waitAsync(this.count, 0, 0);
    }
  }

  // Reset barrier
  reset(): void {
    AtomicsOperations.store(this.waiting, 0, 0);
    AtomicsOperations.store(this.count, 0, 0);
  }
}

// 6. Read-Write Lock
class ReadWriteLock {
  private readers: Int32Array;
  private writer: Int32Array;

  constructor() {
    this.readers = AtomicsOperations.createSharedBuffer(1);
    this.writer = AtomicsOperations.createSharedBuffer(1);
  }

  // Acquire read lock
  async acquireReadLock(): Promise<void> {
    while (true) {
      // Wait if writer is active
      while (AtomicsOperations.load(this.writer, 0) !== 0) {
        await AtomicsOperations.waitAsync(this.writer, 0, 0);
      }

      // Increment readers
      AtomicsOperations.increment(this.readers, 0);

      // Check if writer is still not active
      if (AtomicsOperations.load(this.writer, 0) === 0) {
        return;
      }

      // Writer became active, back off
      AtomicsOperations.decrement(this.readers, 0);
    }
  }

  // Release read lock
  releaseReadLock(): void {
    AtomicsOperations.decrement(this.readers, 0);

    // Notify potential writer if no readers left
    if (AtomicsOperations.load(this.readers, 0) === 0) {
      AtomicsOperations.notify(this.writer, 0, 1);
    }
  }

  // Acquire write lock
  async acquireWriteLock(): Promise<void> {
    // Mark writer as waiting
    while (true) {
      // Wait for readers to finish
      while (AtomicsOperations.load(this.readers, 0) !== 0) {
        await AtomicsOperations.waitAsync(this.readers, 0, 1);
      }

      // Try to acquire write lock
      const previous = AtomicsOperations.compareAndSwap(this.writer, 0, 0, 1);

      if (previous === 0) {
        return;
      }
    }
  }

  // Release write lock
  releaseWriteLock(): void {
    AtomicsOperations.store(this.writer, 0, 0);
    AtomicsOperations.notify(this.writer, 0, 1);
    AtomicsOperations.notify(this.readers, 0, 1);
  }

  // Execute with read lock
  async executeRead<T>(fn: () => Promise<T>): Promise<T> {
    await this.acquireReadLock();
    try {
      return await fn();
    } finally {
      this.releaseReadLock();
    }
  }

  // Execute with write lock
  async executeWrite<T>(fn: () => Promise<T>): Promise<T> {
    await this.acquireWriteLock();
    try {
      return await fn();
    } finally {
      this.releaseWriteLock();
    }
  }
}

// 7. Concurrent Counter
class ConcurrentCounter {
  private counter: Int32Array;

  constructor(initialValue: number = 0) {
    this.counter = AtomicsOperations.createSharedBuffer(1);
    AtomicsOperations.store(this.counter, 0, initialValue);
  }

  // Increment and get
  incrementAndGet(): number {
    return AtomicsOperations.add(this.counter, 0, 1) + 1;
  }

  // Get and increment
  getAndIncrement(): number {
    return AtomicsOperations.add(this.counter, 0, 1);
  }

  // Decrement and get
  decrementAndGet(): number {
    return AtomicsOperations.sub(this.counter, 0, 1) - 1;
  }

  // Get and decrement
  getAndDecrement(): number {
    return AtomicsOperations.sub(this.counter, 0, 1);
  }

  // Get current value
  get(): number {
    return AtomicsOperations.load(this.counter, 0);
  }

  // Set value
  set(value: number): void {
    AtomicsOperations.store(this.counter, 0, value);
  }

  // Add and get
  addAndGet(value: number): number {
    return AtomicsOperations.add(this.counter, 0, value) + value;
  }
}

// 8. Producer-Consumer Queue
class ProducerConsumerQueue<T> {
  private buffer: T[] = [];
  private size: Int32Array;
  private count: Int32Array;
  private head: Int32Array;
  private tail: Int32Array;

  constructor(capacity: number) {
    this.buffer = new Array(capacity);
    this.size = AtomicsOperations.createSharedBuffer(1);
    this.count = AtomicsOperations.createSharedBuffer(1);
    this.head = AtomicsOperations.createSharedBuffer(1);
    this.tail = AtomicsOperations.createSharedBuffer(1);

    AtomicsOperations.store(this.size, 0, capacity);
  }

  // Enqueue item
  async enqueue(item: T): Promise<void> {
    while (true) {
      const currentCount = AtomicsOperations.load(this.count, 0);
      const capacity = AtomicsOperations.load(this.size, 0);

      if (currentCount < capacity) {
        // Not full, enqueue
        const tail = AtomicsOperations.load(this.tail, 0);
        this.buffer[tail] = item;
        AtomicsOperations.store(this.tail, 0, (tail + 1) % capacity);
        AtomicsOperations.increment(this.count, 0);
        AtomicsOperations.notify(this.count, 0, 1);
        return;
      }

      // Full, wait for space
      await AtomicsOperations.waitAsync(this.count, 0, currentCount);
    }
  }

  // Dequeue item
  async dequeue(): Promise<T> {
    while (true) {
      const currentCount = AtomicsOperations.load(this.count, 0);

      if (currentCount > 0) {
        // Not empty, dequeue
        const head = AtomicsOperations.load(this.head, 0);
        const capacity = AtomicsOperations.load(this.size, 0);
        const item = this.buffer[head];

        this.buffer[head] = undefined as any;
        AtomicsOperations.store(this.head, 0, (head + 1) % capacity);
        AtomicsOperations.decrement(this.count, 0);
        AtomicsOperations.notify(this.count, 0, 1);
        return item;
      }

      // Empty, wait for item
      await AtomicsOperations.waitAsync(this.count, 0, currentCount);
    }
  }

  // Get current count
  get count(): number {
    return AtomicsOperations.load(this.count, 0);
  }
}

// Usage Examples
async function demonstrateSynchronization() {
  console.log('=== Web TypeScript Synchronization Primitives Examples ===\n');

  // 1. Atomics operations
  console.log('--- 1. Atomics Operations ---');
  const buffer = AtomicsOperations.createSharedBuffer(5);

  for (let i = 0; i < buffer.length; i++) {
    AtomicsOperations.store(buffer, i, i * 10);
  }

  console.log('Buffer values:');
  for (let i = 0; i < buffer.length; i++) {
    console.log(`  [${i}] = ${buffer[i]}`);
  }

  AtomicsOperations.add(buffer, 0, 5);
  console.log(`After add to [0]: ${buffer[0]}`);

  // 2. Concurrent counter
  console.log('\n--- 2. Concurrent Counter ---');
  const counter = new ConcurrentCounter(0);

  // Simulate concurrent increments
  const incrementTasks = Array.from({ length: 10 }, (_, i) =>
    PromiseBasics.delay(Math.random() * 100).then(() => {
      counter.incrementAndGet();
    })
  );

  await Promise.all(incrementTasks);
  console.log(`Final counter value: ${counter.get()}`);

  // 3. Mutex
  console.log('\n--- 3. Mutex ---');
  const mutex = new Mutex();
  let sharedResource = 0;

  const mutexTasks = Array.from({ length: 5 }, (_, i) =>
    mutex.execute(async () => {
      const value = sharedResource;
      console.log(`Task ${i} read: ${value}`);
      await PromiseBasics.delay(50);
      sharedResource = value + 1;
      console.log(`Task ${i} wrote: ${sharedResource}`);
      return sharedResource;
    })
  );

  await Promise.all(mutexTasks);
  console.log(`Final shared resource value: ${sharedResource}`);

  // 4. Semaphore
  console.log('\n--- 4. Semaphore ---');
  const semaphore = new Semaphore(2); // Allow 2 concurrent operations

  let activeCount = 0;
  let maxActive = 0;

  const semaphoreTasks = Array.from({ length: 10 }, (_, i) =>
    semaphore.execute(async () => {
      activeCount++;
      maxActive = Math.max(maxActive, activeCount);
      console.log(`Task ${i} started (active: ${activeCount})`);
      await PromiseBasics.delay(Math.random() * 200);
      activeCount--;
      console.log(`Task ${i} completed`);
    })
  );

  await Promise.all(semaphoreTasks);
  console.log(`Max concurrent tasks: ${maxActive}`);

  // 5. Barrier
  console.log('\n--- 5. Barrier ---');
  const barrier = new Barrier(3);

  const barrierTasks = Array.from({ length: 3 }, (_, i) =>
    barrier.wait().then(() => {
      console.log(`Task ${i} passed barrier`);
    })
  );

  await Promise.all(barrierTasks);

  // 6. Producer-Consumer
  console.log('\n--- 6. Producer-Consumer Queue ---');
  const queue = new ProducerConsumerQueue<number>(5);

  // Producer
  queue.enqueue(1);
  setTimeout(() => queue.enqueue(2), 100);
  setTimeout(() => queue.enqueue(3), 200);

  // Consumer
  const item1 = await queue.dequeue();
  console.log(`Dequeued: ${item1}`);

  const item2 = await queue.dequeue();
  console.log(`Dequeued: ${item2}`);

  console.log(`Queue count: ${queue.count}`);

  console.log('\n=== All Synchronization Primitives Examples Completed ===');
}

// Import PromiseBasics
class PromiseBasics {
  static delay(ms: number): Promise<void> {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
}

// Export classes
export { AtomicsOperations, Spinlock, Mutex, Semaphore, Barrier, ReadWriteLock, ConcurrentCounter, ProducerConsumerQueue };
export { demonstrateSynchronization };

Инструменты

Инструменты, которые часто используются с этим примером

Связано

Похожие коллекции примеров

Руководство по использованию инструмента

Контекст для понимания этой коллекции примеров

Заголовок

Примеры Многопоточности Web TypeScript

Описание

Примеры многопоточности Web TypeScript включая Web Workers, асинхронные операции и параллельную обработку

Обзор

Примеры многопоточности Web TypeScript включая Web Workers, асинхронные операции и параллельную обработку

Когда использовать

  • Use this sample set when you want reference inputs for Примеры Многопоточности Web TypeScript.
  • Use it to preview output formats and compare related sample variants.

Как это работает

  1. 1Open a sample entry to inspect the prepared example payload or asset.
  2. 2Compare it with related tools to understand how the workflow connects.

Сценарии использования

  • Web Workers
  • Асинхронные Операции
  • Примитивы Синхронизации

FAQ

What is included in Примеры Многопоточности Web TypeScript?

This page includes curated sample entries, related tools, and neighboring sample collections for Примеры Многопоточности Web TypeScript.

Главная
Инструменты3197
Примеры593
Визуализации461
Средства просмотра файлов103
Темы229
Теги333
Изображения, аудио и видео655

Инструменты для обработки, конвертации и оптимизации изображений, аудио и видео

Математика, даты и финансы644

Калькуляторы, числовые инструменты, логика дат, статистика и финансы

Дизайн и цвет296

Инструменты для цвета, макетов, графики, визуального стиля и дизайна

Текст и письмо209

Инструменты для письма, очистки, форматирования, извлечения и анализа текста

Разработка и Web193

Инструменты разработчика, сетевые утилиты, веб-отладка и автоматизация

Преобразование и кодирование175

Инструменты для преобразования форматов, файлов, архивов, единиц и кодировок

Структура интерфейса по скриншоту: проверка и передача разработчику
Фортепианный эскиз: создание, проверка MIDI и передача аудиодемо
Проверка ретро-текстур и передача игровых ресурсов
Проверка и передача пошагового руководства со снимками
Визуальная проверка адаптивной страницы после редизайна

© 2026 Elysia Tools. Все права защищены.

ДокументацияТарифыО насУсловия использованияПолитика конфиденциальностиCookieКонтакты

Development

JSON в TypeScript

Преобразует данные JSON в интерфейсы TypeScript или псевдонимы типов с поддержкой объединений, необязательных полей и вложенных объектов

Web & Internet

Веб-поиск (JSON SearXNG)

Ищет в интернете через экземпляр SearXNG s.stdlang.com и возвращает JSON для автоматизации и других инструментов.

Development

Генератор OpenAPI в TypeScript

Преобразует спецификации OpenAPI или Swagger в формате JSON/YAML в типы TypeScript, параметры запросов и модели ответов с настраиваемым форматом вывода и стилем имен

Media

Изменение размера скриншотов Chrome Web Store

Изменение размера изображений до размеров скриншотов Chrome Web Store (1280x800 или 640x400) для листингов расширений и приложений

Format Conversion

Кодировщик Web Push: запрос RFC 8030 + VAPID + шифрование RFC 8291

Кодирует полную отправку Web Push: шифрование aes128gcm по RFC 8291, VAPID ES256 JWT по RFC 8292, заголовки RFC 8030, соответствие APNs/FCM и проверку расшифровкой в оба направления.

Design

Лаборатория Подбора Веб-Шрифтов

Предпросмотр пары Google Fonts (заголовок + текст) с настройкой веса и межстрочного, плюс готовый CSS-сниппет с @import и переменными. Кураторский список из 22 шрифтов и 7 проверенных пресетов.

Media

Пакетная Обрезка Изображений

Одновременная обрезка нескольких изображений различными методами с выводом в ZIP

Health

Калькулятор Группы Крови

Рассчитывает возможные группы крови для родителей и детей на основе генетики

Rust

Примеры Многопоточности Web Rust

Примеры многопоточности Web Rust включая создание потоков, синхронизацию и пул потоков

TypeScript

Примеры Криптографии Web TypeScript

Примеры криптографии Web TypeScript включая вычисление хэша, симметричное шифрование и кодирование Base64

TypeScript

Примеры Операций с Базой Данных Web TypeScript

Примеры операций с базой данных Web TypeScript включая подключение SQLite, выполнение SQL-запросов и управление транзакциями

TypeScript

Примеры Структур Данных Web TypeScript

Примеры структур данных Web TypeScript включая операции с массивами, хеш-таблицы и связные списки

TypeScript

Примеры Даты и Времени Web TypeScript

Примеры даты и времени Web TypeScript включая получение текущего времени, форматирование, парсинг и манипуляцию

TypeScript

Примеры Функций Настольного Веб TypeScript

Примеры функций настольного веба Web TypeScript включая файловые диалоги, окна сообщений и системный трей