🌐 Detecting your location…
📢 Advertisement — Configure AdSense in Appearance → Customize → AdSense Settings

टाइपस्क्रिप्ट एडवांस्ड एसिंक पैटर्न 2026: सिग्नल, कैंसिलेशन और स्ट्रीम

⏱️5 min read  ·  966 words

2026 में टाइपस्क्रिप्ट एसिंक पैटर्न बुनियादी एसिंक/प्रतीक्षा से कहीं आगे जाते हैं। संरचित समवर्ती, टाइप किए गए ईवेंट एमिटर, सिग्नल के साथ प्रतिक्रियाशील धाराएं, और उचित त्रुटि प्रबंधन काम करने वाले एसिंक कोड और बनाए रखने योग्य एसिंक कोड के बीच अंतर बनाते हैं। यह मार्गदर्शिका वरिष्ठ टाइपस्क्रिप्ट डेवलपर्स द्वारा उपयोग किए जाने वाले पैटर्न को कवर करती है।

टाइप किया गया वादा उपयोगिताएँ

// Type-safe promise utilities
type Awaited<T> = T extends Promise<infer U> ? U : T;
type MaybePromise<T> = T | Promise<T>;

// allSettled with typed results
async function settleAll<T extends readonly unknown[]>(
  promises: { [K in keyof T]: Promise<T[K]> }
): Promise<{ [K in keyof T]: { ok: true; value: T[K] } | { ok: false; error: unknown } }> {
  const results = await Promise.allSettled(promises);
  return results.map(r =>
    r.status === 'fulfilled' ? { ok: true, value: r.value } : { ok: false, error: r.reason }
  ) as any;
}

// Race with timeout
async function withTimeout<T>(promise: Promise<T>, ms: number, message?: string): Promise<T> {
  const timeout = new Promise<never>((_, reject) =>
    setTimeout(() => reject(new Error(message ?? `Timed out after ${ms}ms`)), ms)
  );
  return Promise.race([promise, timeout]);
}

// Retry with exponential backoff
async function retry<T>(
  fn: () => Promise<T>,
  options: { maxAttempts?: number; delay?: number; backoff?: number } = {}
): Promise<T> {
  const { maxAttempts = 3, delay = 1000, backoff = 2 } = options;
  let lastError: unknown;
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    try {
      return await fn();
    } catch (err) {
      lastError = err;
      if (attempt < maxAttempts) {
        await new Promise(r => setTimeout(r, delay * Math.pow(backoff, attempt - 1)));
      }
    }
  }
  throw lastError;
}

// Usage
const [user, posts] = await settleAll([fetchUser(1), fetchPosts(1)] as const);
if (user.ok && posts.ok) {
  displayDashboard(user.value, posts.value);
}

Async कतार और वर्कर पूल

class AsyncQueue<T> {
  private queue: Array<{ item: T; resolve: () => void }> = [];
  private workers = 0;
  private readonly maxWorkers: number;
  private readonly processor: (item: T) => Promise<void>;

  constructor(processor: (item: T) => Promise<void>, maxWorkers = 5) {
    this.processor = processor;
    this.maxWorkers = maxWorkers;
  }

  async add(item: T): Promise<void> {
    return new Promise(resolve => {
      this.queue.push({ item, resolve });
      this.processNext();
    });
  }

  private async processNext(): Promise<void> {
    if (this.workers >= this.maxWorkers || this.queue.length === 0) return;

    this.workers++;
    const { item, resolve } = this.queue.shift()!;

    try {
      await this.processor(item);
    } finally {
      resolve();
      this.workers--;
      this.processNext();
    }
  }

  async drain(): Promise<void> {
    while (this.queue.length > 0 || this.workers > 0) {
      await new Promise(r => setTimeout(r, 10));
    }
  }
}

// Usage
const emailQueue = new AsyncQueue<Email>(
  async (email) => { await sendEmail(email); },
  10 // max 10 concurrent emails
);

for (const user of users) {
  await emailQueue.add({ to: user.email, subject: "Welcome!" });
}
await emailQueue.drain();

सिग्नल – प्रतिक्रियाशील अवस्था (2026)

// TC39 Stage 3 Signals (available in 2026)
import { Signal } from 'signal-polyfill';

// Reactive primitive
const count = new Signal.State(0);
const doubled = new Signal.Computed(() => count.get() * 2);
const greeting = new Signal.Computed(() => `Count is ${count.get()}, doubled: ${doubled.get()}`);

// In React (via @preact/signals-react or use-signals)
function Counter() {
  return (
    <div>
      <p>{greeting}</p>
      <button onClick={() => count.set(count.get() + 1)}>Increment</button>
    </div>
  );
}

// Server-side signals for streaming
const streamData = new Signal.State<string[]>([]);

// Push data as it arrives
async function streamFromAPI() {
  const response = await fetch('/api/stream');
  const reader = response.body!.getReader();
  const decoder = new TextDecoder();

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    const chunk = decoder.decode(value);
    streamData.set([...streamData.get(), chunk]); // reactive update
  }
}

एबॉर्टकंट्रोलर – रद्दीकरण

// Proper cancellation with AbortController
class CancellableFetcher {
  private controllers = new Map<string, AbortController>();

  async fetch<T>(key: string, url: string, options?: RequestInit): Promise<T> {
    // Cancel previous request with same key
    this.cancel(key);

    const controller = new AbortController();
    this.controllers.set(key, controller);

    try {
      const response = await fetch(url, {
        ...options,
        signal: controller.signal,
      });

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }

      return response.json() as Promise<T>;
    } catch (err) {
      if (err instanceof DOMException && err.name === 'AbortError') {
        throw new Error('Request cancelled');
      }
      throw err;
    } finally {
      this.controllers.delete(key);
    }
  }

  cancel(key: string): void {
    this.controllers.get(key)?.abort();
  }

  cancelAll(): void {
    this.controllers.forEach(c => c.abort());
    this.controllers.clear();
  }
}

// React hook with auto-cancellation
function useAsync<T>(fn: () => Promise<T>, deps: unknown[]) {
  const [state, setState] = useState<{
    data: T | null; loading: boolean; error: Error | null
  }>({ data: null, loading: true, error: null });

  useEffect(() => {
    const controller = new AbortController();
    let cancelled = false;

    fn()
      .then(data => !cancelled && setState({ data, loading: false, error: null }))
      .catch(err => !cancelled && setState({ data: null, loading: false, error: err }));

    return () => {
      cancelled = true;
      controller.abort();
    };
  }, deps);

  return state;
}

AsyncIterable के साथ अवलोकनीय पैटर्न

// Create an observable stream from events
async function* fromEvents<T>(
  emitter: EventTarget,
  event: string,
  signal?: AbortSignal
): AsyncGenerator<T> {
  const queue: T[] = [];
  let resolve: (() => void) | null = null;

  const handler = (e: Event) => {
    queue.push((e as CustomEvent<T>).detail);
    resolve?.();
    resolve = null;
  };

  emitter.addEventListener(event, handler);
  signal?.addEventListener('abort', () => emitter.removeEventListener(event, handler));

  try {
    while (!signal?.aborted) {
      if (queue.length > 0) {
        yield queue.shift()!;
      } else {
        await new Promise<void>(r => { resolve = r; });
      }
    }
  } finally {
    emitter.removeEventListener(event, handler);
  }
}

// Pipeline operators for async iterables
async function* map<T, U>(iterable: AsyncIterable<T>, fn: (x: T) => U): AsyncGenerator<U> {
  for await (const item of iterable) {
    yield fn(item);
  }
}

async function* filter<T>(iterable: AsyncIterable<T>, pred: (x: T) => boolean): AsyncGenerator<T> {
  for await (const item of iterable) {
    if (pred(item)) yield item;
  }
}

async function* take<T>(iterable: AsyncIterable<T>, n: number): AsyncGenerator<T> {
  let count = 0;
  for await (const item of iterable) {
    if (count++ >= n) break;
    yield item;
  }
}

// Usage: live data pipeline
const controller = new AbortController();
const events = fromEvents<SensorReading>(sensorHub, 'reading', controller.signal);
const filtered = filter(events, r => r.value > threshold);
const mapped = map(filtered, r => ({ ...r, normalized: r.value / maxValue }));
const firstTen = take(mapped, 10);

for await (const reading of firstTen) {
  dashboard.update(reading);
}

2026 में टाइपस्क्रिप्ट एसिंक पैटर्न किसी भी भाषा की एसिंक कहानी जितना ही शक्तिशाली है। लचीलेपन के लिए टाइप किए गए रिट्री/टाइमआउट रैपर्स, क्लीन कैंसिलेशन के लिए एबॉर्टकंट्रोलर, बैकप्रेशर के लिए AsyncQueue और स्ट्रीमिंग डेटा पाइपलाइनों के लिए AsyncIterable का उपयोग करें। सिग्नल (TC39 स्टेज 3) बाहरी पुस्तकालयों के बिना घटक-स्तरीय स्थिति के लिए प्रतिक्रियाशील आदिम हैं।

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇬🇧 English🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা