JS Promise

gleng

JS Promise
« kdy: 29. 12. 2021, 23:21:24 »
S Promise a await som v zivote v JS nerobil a ani sa nechystam ale mam tu jednu situaciu kedy ich potrebujem a neviem si rady.

Mam funkciu ktora urobi request na externe api a streamuje z neho data. Potrebujem z vonku predat tejto funkcii promise a ked sa resolvne tak sa vnutri funkcie uzatvori spojenie na to externe api a prestane z neho streamovat data.

nieco ako
Citace
function streamData(do, cancel) {
  ...
  do(data) // nech nieco spravi s nastreamovanymi datami
  cancel.then(() => api.stop())
}

let closer = new Promise((resolve)  => {
      setTimeout(resolve, 10000)
});

streamData(console.log, closer)

A ja potrebujem ten promise resolvnut az kedy ja potrebujem skratka, niekde z vonku. Co som cital tak promise zavola hned ten exekutor ktory ma resolve a reject argumenty(mam tu len resolve) tak nejak neviem vymysliet aku funkciu tomu dat aby to cakalo az na moj povel proste.

Taktiez by asi funkcia streamData mala asi vratit promise, alebo sa nejak **** do pozadia, nech neblokuje exekuciu dalsieho kodu. Proste nech si streamuje niekde v pozadi a ja o nej neviem dokial ju nezrusim s tym resolve.


Re:JS Promise
« Odpověď #1 kdy: 29. 12. 2021, 23:47:57 »
V tom, co potřebujete, se nikde žádné Promise nevyskytuje. Prostě jenom z té funkce streamData vrátíte funkci, jejímž zavoláním se streamování zastaví:

Kód: [Vybrat]
const streamData = (do) => {
  ...
  do(data) // nech nieco spravi s nastreamovanymi datami
  return () => api.stop()
}

const cancel = streamData(console.log)
setTimeout(cancel, 10000)

Dalo by se to udělat i s tím Promise, jenom si tu proměnnou resolve musíte vytáhnout někam ven. Řešení na prasáka by bylo uložit to do globální proměnné, lepší řešení je zapouzdřit to do funkce a z té vracet Promise i tu ukončovací funkci.




L..

  • ***
  • 194
    • Zobrazit profil
    • E-mail
Re:JS Promise
« Odpověď #2 kdy: 29. 12. 2021, 23:57:29 »
Promise se používá na situaci, kdy něco zavoláš co dá výsledek až po nějaké době (třeba až dojdou data po síti) a chceš zavolat callback v okamžiku, kdy ta data jsou ready.

Na tohle je nepotřebuješ, mrkni na stream API: https://nodejs.org/api/stream.html

Prostě otevřeš stream, ten bude na event data ty data zpracovávat. No a až budeš chtít skončit, tak na ten stream zavoláš destroy.

gleng

Re:JS Promise
« Odpověď #3 kdy: 30. 12. 2021, 00:16:47 »
V tom, co potřebujete, se nikde žádné Promise nevyskytuje. Prostě jenom z té funkce streamData vrátíte funkci, jejímž zavoláním se streamování zastaví:...

Ten stream je kontinualny a vzdy ked mu pridu data tak ich "posle" to tej do() funkcie. ja na ten stream necakam kym skonci. on bezi stale v pozadi skratka. preto nemozem cakat kym skonci a vrati nieco.


Citace
Promise se používá na situaci, kdy něco zavoláš co dá výsledek až po nějaké době (třeba až dojdou data po síti) a chceš zavolat callback v okamžiku, kdy ta data jsou ready.

Precitaj si znovu moju otazku. Ak nieco stale nie je jasne tak doplnim.

Re:JS Promise
« Odpověď #4 kdy: 30. 12. 2021, 00:34:50 »
Precitaj si znovu moju otazku. Ak nieco stale nie je jasne tak doplnim.
To vy chcete poradit. Otázku si není potřeba číst znova, protože to, co píšete v otázce, nedává žádný smysl. Napište, v jakém prostředí se pohybujete (prohlížeč, Node.js, něco jiného), co přesně je ten stream, co přesně potřebujete vyřešit. Pak teprve můžeme poradit, jak to řešit.

Ten stream je kontinualny a vzdy ked mu pridu data tak ich "posle" to tej do() funkcie. ja na ten stream necakam kym skonci. on bezi stale v pozadi skratka. preto nemozem cakat kym skonci a vrati nieco.
Já jsem ale nepsal, že máte čekat na dokončení streamu, ale na dokončení té vaší funkce, která asi zahajuje čtení ze streamu. Vzhledem k tomu, že nevíme, co ten váš kód vlastně dělá, nemůžu k tomu napsat nic víc.

JavaScript se chová, jako by byl jednovláknový (ponechme stranou WebWorkery). Pokud by to vaše čtení ze streamu bylo blokující, nikdy nemůžete zavolat nějaký jiný kód, který by ho ukončil. Ono ale nejspíš blokující není – akorát potřebujeme vědět, co je ten stream zač, pokud vám máme poradit, jak přesně s ním pracovat.


gleng

Re:JS Promise
« Odpověď #5 kdy: 30. 12. 2021, 02:22:08 »
Tu je priblizna funkcia:

Kód: [Vybrat]
streamData(req, cancel, ok, nok) {
    let query = new URLSearchParams(req);
    let events = new EventSource(client.defaults.baseURL + "/api/data?" + query.toString());
    events.addEventListener("data", (event) => ok(JSON.parse(event.data)))
    events.onerror = (err) => nok(err)
    cancel.then(() => events.close())
  },

tu je volanie:
Kód: [Vybrat]
   let closer = new Promise((resolve)  => {
     setTimeout(resolve, 10000)
   });
    streamData(
      {id: "foo"},
      closer,
      (data) => console.log(data),
      (err) => console.error(err),
    )


a potom ak uzivatel ide na inu stranku alebo chce stream zastavit tlacidlom tak zavolat nieco ako closer.resolve() namiesto toho timeoutu ktory je len na skusku tam.

Kód: [Vybrat]
JavaScript se chová, jako by byl jednovláknový
Ano, viem. Preto sa tymto veciam v JS radsej vyhybam(aj tak som backendak).

Re:JS Promise
« Odpověď #6 kdy: 30. 12. 2021, 03:18:17 »
Kód: [Vybrat]
function Closer() {
    let r;
    const p = new Promise((resolve, reject) => {
        r = resolve
    });
    p.resolve = r;
    return p;
}

const closer = Closer();
« Poslední změna: 30. 12. 2021, 03:24:32 od A.P.Hacker »

L..

  • ***
  • 194
    • Zobrazit profil
    • E-mail
Re:JS Promise
« Odpověď #7 kdy: 30. 12. 2021, 06:18:36 »
Tu je priblizna funkcia:

No, konečně se někam dostáváme. Z té funkce
Kód: [Vybrat]
streamData() vrať ty
Kód: [Vybrat]
events, ulož si je někam a až budeš chtít skončit, zavolej na nich
Kód: [Vybrat]
events.close(). Případně pokud bys to chtěl zapouzdřit, tak ze
Kód: [Vybrat]
streamData() vrať funkci, která to skončí:

Kód: [Vybrat]
  return () => events.close();

Ale v každém případě je tady použití Promise patternu nesmyslné.

Re:JS Promise
« Odpověď #8 kdy: 30. 12. 2021, 09:13:16 »
Je to přesně jak píše L.., případně jak jsem to psal hned v první odpovědi. Ta varianta s vrácením vlastní funkce (místo celého EventSource) je z hlediska návrhu čistší. Nezveřejňujete implementační detaily, ale vracíte vlastní API – funkci, pomocí které je možné ukončit načítání (a volající nemusí řešit, jak přesně je načítání řešené, prostě má jenom funkci, která načítání ukončí).

Jinak ta funkce streamData je neblokující – zahájí stahování a nastaví posluchače událostí a ukončí se. Takže není problém poslední řádek změnit na return, vrátit z funkce streamData ukončovací funkci a tu někdy později zavolat.

Promise do toho vůbec netahejte, nejsou potřeba a akorát by kód zatemnily.

Re:JS Promise
« Odpověď #9 kdy: 30. 12. 2021, 09:50:56 »
konstrukt, ktery chcete, se jmenuje defer nebo deferred

jak pisi jini, vetsinou je to antipattern

gleng

Re:JS Promise
« Odpověď #10 kdy: 31. 12. 2021, 13:59:52 »
Kód: [Vybrat]
function Closer() {
    let r;
    const p = new Promise((resolve, reject) => {
        r = resolve
    });
    p.resolve = r;
    return p;
}

const closer = Closer();

toto som hladal, diky. zatial to funguje, ak to bude robit neskor problemy tak to prerobim. eventuelne mozno pouzijem websocket a budem to riesit uplne inak.

Re:JS Promise
« Odpověď #11 kdy: 31. 12. 2021, 15:45:59 »
Kód: [Vybrat]
function Closer() {
    let r;
    const p = new Promise((resolve, reject) => {
        r = resolve
    });
    p.resolve = r;
    return p;
}

const closer = Closer();

toto som hladal, diky. zatial to funguje, ak to bude robit neskor problemy tak to prerobim. eventuelne mozno pouzijem websocket a budem to riesit uplne inak.

Když odstraníte to zbytečné Promise, dostanete kód, o kterém jsem psal já a L..

Re:JS Promise
« Odpověď #12 kdy: 31. 12. 2021, 15:55:59 »
Když odstraníte to zbytečné Promise, dostanete kód, o kterém jsem psal já a L..

on presne specifikoval, jake chce API.

ja bych asi pouzil tohle https://www.npmjs.com/package/p-defer
« Poslední změna: 31. 12. 2021, 15:59:00 od A.P.Hacker »

Re:JS Promise
« Odpověď #13 kdy: 31. 12. 2021, 16:50:44 »
on presne specifikoval, jake chce API.
Což nic nemění na tom, že je to nesmysl.

ja bych asi pouzil tohle https://www.npmjs.com/package/p-defer
Ano, zejména by bylo dobré se držet té tučné červené věty na začátku: „Don't use this unless you know what you're doing.“

Re:JS Promise
« Odpověď #14 kdy: 31. 12. 2021, 17:55:27 »
Kurna, to se mi ani cist poradne nechtelo, takvy zmateny dotaz. Dam ti tip, ujasni si:

1. Co je to promis
2. Co je to asynchronni volani funkce
3. K cemu je async a await keywords
4. Proc node.js standardni knihovni funkce nevraci promis - protoze jsou stare.
5. Jak si muzes libovolnou starou asynchronni funkci v node.js sam predelat na promis
6. A jak si nad tim pak muzes pouzit async await.

A mas to. A jestl ito chces mit komplet, tak jeste

7. Co je to event loop v node.js a web browseru
« Poslední změna: 31. 12. 2021, 17:59:18 od registrovany123 »