/ Gists / JS news
On gists

JS news

JavaScript

index.js Raw #

/*
========================================================
Modern JavaScript – Useful New APIs
========================================================

Krátký přehled několika moderních JS funkcí a API,
které zjednodušují async kód, práci s daty a generování ID.

Obsah:
1. crypto.randomUUID()
2. Iterator helpers
3. Promise.withResolvers()
4. Promise.try()
5. AbortSignal.timeout()
6. AbortSignal.any()
7. structuredClone()

========================================================
*/


/*
========================================================
1. crypto.randomUUID()
========================================================

Generuje kryptograficky bezpečný UUID v4.
Není potřeba externí knihovna (např. uuid npm balík).
*/

const id = crypto.randomUUID();

console.log("UUID:", id);
// example: "36b8f84d-df4e-4d49-b662-bcde71a8764f"

/*
Use cases
- generování ID objektů
- correlation id pro requesty
- temporary keys
- client side identifiers
*/



/*
========================================================
2. Iterator Helpers
========================================================

Umožňují lazy operace nad iterátory.

Výhoda:
- nevytváří mezilehlá pole
- efektivnější pro velké datasety
- umožňují nekonečné sekvence
*/


// klasický array chain (vytváří mezivýsledky)

const arrayResult = [1,2,3,4,5]
  .map(x => x * 2)
  .filter(x => x > 5);

console.log("Array result:", arrayResult);


// iterator chain (lazy evaluation)

const iteratorResult =
  Iterator.from([1,2,3,4,5])
    .map(x => x * 2)
    .filter(x => x > 5)
    .toArray();

console.log("Iterator result:", iteratorResult);


// nekonečná sekvence

function* numbers() {
  let i = 0;
  while (true) {
    yield i++;
  }
}

const infiniteExample =
  Iterator.from(numbers())
    .map(x => x * 2)
    .take(5)
    .toArray();

console.log("Infinite sequence:", infiniteExample);




/*
========================================================
3. Promise.withResolvers()
========================================================

Elegantní způsob jak vytvořit Promise s externím
resolve / reject.

Nahrazuje starý "deferred promise" pattern.
*/


// moderní způsob

const { promise, resolve } = Promise.withResolvers();

setTimeout(() => {
  resolve("done");
}, 1000);

promise.then(console.log);



// example: wait for event

function waitForEvent(emitter, event) {

  const { promise, resolve } = Promise.withResolvers();

  emitter.once(event, resolve);

  return promise;

}



/*
========================================================
Async Queue Example
========================================================
*/

class AsyncQueue {

  constructor() {
    this.items = [];
    this.waiter = null;
  }

  push(item) {

    if (this.waiter) {
      this.waiter.resolve(item);
      this.waiter = null;
      return;
    }

    this.items.push(item);

  }

  async pop() {

    if (this.items.length) {
      return this.items.shift();
    }

    this.waiter = Promise.withResolvers();
    return this.waiter.promise;

  }

}



/*
========================================================
4. Promise.try()
========================================================

Pomáhá sjednotit sync a async funkce.

Automaticky zachytí chyby a vrátí rejected Promise.
*/


Promise.try(() => {
  return 5;
}).then(console.log);


// error handling

Promise.try(() => {
  throw new Error("boom");
}).catch(console.error);



// wrapper pattern

function run(handler) {
  return Promise.try(handler);
}

run(() => 5);
run(async () => fetch("/api"));
run(() => { throw "error"; });



/*
========================================================
5. AbortSignal.timeout()
========================================================

Jednoduché řešení timeoutů pro async operace.
Typicky se používá s fetch.
*/


async function fetchWithTimeout(url) {

  const response = await fetch(url, {
    signal: AbortSignal.timeout(5000)
  });

  return response.json();

}




/*
========================================================
6. AbortSignal.any()
========================================================

Kombinuje více abort signálů.

Operace se zruší pokud kterýkoliv signal abortne.
*/


async function fetchWithCancel(url) {

  const controller = new AbortController();

  const signal = AbortSignal.any([
    controller.signal,
    AbortSignal.timeout(5000)
  ]);

  const request = fetch(url, { signal });

  return {
    request,
    cancel: () => controller.abort()
  };

}



// example usage

async function example() {

  const { request, cancel } = fetchWithCancel("/api/data");

  setTimeout(cancel, 1000);

  try {
    const res = await request;
    console.log(await res.json());
  } catch (err) {
    console.log("Request cancelled or timeout");
  }

}



/*
========================================================
7. structuredClone()
========================================================

Nativní deep clone objektů.

Výhoda oproti JSON stringify:
- zachová typy
- funguje s Map, Set, Date, ArrayBuffer
*/


const original = {
  user: { name: "John" },
  created: new Date(),
  tags: new Set(["a","b"])
};

const clone = structuredClone(original);

console.log(original);
console.log(clone);



/*
========================================================
JSON clone problem
========================================================
*/

const badClone = JSON.parse(JSON.stringify(original));

// Date se změní na string
console.log("JSON clone:", badClone);



/*
========================================================
Summary
========================================================

Nejužitečnější moderní JS API:

crypto.randomUUID()
- generování unikátních ID

Iterator helpers
- lazy zpracování dat

Promise.withResolvers()
- async eventy, queue

Promise.try()
- sjednocení sync/async kódu

AbortSignal.timeout()
- timeout async operací

AbortSignal.any()
- kombinace více cancel signálů

structuredClone()
- deep clone objektů

========================================================
*/