Autor | Zpráva | ||
---|---|---|---|
hypot Profil |
#1 · Zasláno: 30. 5. 2019, 17:07:25
Snažím se porozumět slibům (promises) a když už jsem myslel, že aspoň tomu základnímu rozumím, hned mě jedna věc zaskočila.
Následující cvičný kód vypíše do konzole text promise a, pak pět vteřin počká, pak vypíše další text promise b, pak zase počká pět vteřin a nakonec vypíše poslední (třetí) text promise c: new Promise(function(resolve) { resolve("promise a"); }).then((z_a) => { console.log(z_a); return new Promise(function(resolve) { setTimeout(function() { resolve("promise b"); }, 5000); }); }).then((z_b) => { console.log(z_b); return new Promise(function(resolve) { setTimeout(function() { resolve("promise c"); }, 5000); }); }).then((z_c) => { console.log(z_c); }) function a() { return new Promise(function(resolve) { resolve("promise a"); }) }; function b() { return new Promise(function(resolve) { setTimeout(function() { resolve("promise b"); }, 5000); }) }; function c() { return new Promise(function(resolve) { setTimeout(function() { resolve("promise c"); }, 5000); }) }; a().then((z_a) => { console.log(z_a); return b(); }).then((z_b) => { console.log(z_b); return c(); }).then((z_c) => { console.log(z_c); }) Pak jsem si řekl, že slib je objekt a že si to proto můžu ještě trochu upravit (ušetřím závorky) a zapíšu to takto: var a = new Promise(function(resolve) { resolve("promise a"); }); var b = new Promise(function(resolve) { setTimeout(function() { resolve("promise b"); }, 5000); }); var c = new Promise(function(resolve) { setTimeout(function() { resolve("promise c"); }, 5000); }); a.then((z_a) => { console.log(z_a); return b; }).then((z_b) => { console.log(z_b); return c; }).then((z_c) => { console.log(z_c); }) Koukal jsem na to dlouho, ale nebyl jsem schopen přijít na to, čím se od sebe varianta B a varianta C z hlediska funkčnosti liší. Čím tedy? |
||
Radek9 Profil |
hypot:
Liší se to v tom, že v poslední ukázce se ty timeouty spustí ihned (tzn. rovnou při definici těch promisů na řádcích 5 a 11). Což nemusí být nutně špatně. Zkus si to představit jinak: Chceš načíst seznam uživatelů a potom data o jednom konkrétním uživateli. V tu chvíli použiješ model podle tvé první či druhé ukázky, protože potřebuješ nejdřív ten seznam uživatelů, abys mohl spustit další požadavek. Takže voláš: loadUsers() .then(function (users) { console.log(users) return loadSingleUserData(users[0]) // Požadavek (nebo timeout) se spustí až tady }) .then(function (userData) { console.log(userData) }) Pokud to jsou ale nezávislé požadavky, můžeš je spustit zároveň (tvoje třetí ukázka): const a = loadSingleUserData(123) const b = loadSingleUserData(456) // oba požadavky (nebo timeouty) se už spustily a .then(function (userA) { console.log(userA) return b }) .then(function (userB) { console.log(userB) }) Nicméně v tuhle chvíli úplně nedává smysl řetězení (protože jsou ty požadavky nezávislé). Lepší je použít funkci Promise.all , která ti vrátí oba výsledky zároveň:
const a = loadSingleUserData(123) const b = loadSingleUserData(456) // oba požadavky (nebo timeouty) se už spustily Promise.all([a, b]) .then(function ([userA, userB]) { console.log(userA) console.log(userB) }) Jednoduše řečeno tedy prostě záleží, kdy ten promise vytvoříš. Pokud ti záleží na doběhnutí předchozích, musíš ho vytvořit až potom. Pokud ti na tom nezáleží, můžeš je vytvořit všechny současně. |
||
hypot Profil |
#3 · Zasláno: 31. 5. 2019, 14:43:14
Já se obávám, že to, čemu nerozumím, potom ani tak nesouvisí se sliby. Stále totiž nerozumím tomu, proč se v mé variantě B ty timeouty nespustí hned, kdežto ve variantě C se spustí hned.
Když udělám přehled použití metody setTimeout: A) setTimeout(() => console.log("nějaký text"), 5000) : timeout se spustí hned B) const a = setTimeout(() => console.log("nějaký text"), 5000) : timeout se spustí hned C) const a = () => setTimeout(() => console.log("nějaký text"), 5000) : timeout se nespustí hned D) const objekt = {a: setTimeout(() => console.log("nějaký text"), 5000)} : timeout se spustí hned E) const objekt = {a: () => setTimeout(() => console.log("nějaký text"), 5000)} : timeout se nespustí hned F) function a() {setTimeout(() => console.log("nějaký text"), 5000)}: timeout se nespustí hned A jestliže mám const a = Promise((...) => setTimeout(() => resolve("nějaký text"), 5000)) domníval jsem se, že to odpovídá variantě C). |
||
Radek9 Profil |
hypot:
„proč se v mé variantě B ty timeouty nespustí hned, kdežto ve variantě C se spustí hned.“ Protože ta funkce, kterou předáváš do Promise , se spouští okamžitě. Takže v B se spustí, až když se ten promise vytvoří (tedy po zavolání příslušné funkce a , b nebo c ). V C vytváříš promise rovnou, proto se i timeout spustí rovnou.
> A jestliže mám > const a = Promise((...) => setTimeout(() => resolve("nějaký text"), 5000)) > domníval jsem se, že to odpovídá variantě C Neodpovídá. Jak jsem psal výše, ta funkce, kterou předáš, se volá hned. Ten promise nezajímá, jestli na něj něco čeká. Prostě to rovnou provede. Odpovídá to A, B nebo D. |
||
Kajman Profil |
#5 · Zasláno: 31. 5. 2019, 15:34:35
hypot:
Definováním funkce se její obsah nespustí. Obsah se spustí až jejím spuštěním. |
||
Časová prodleva: 6 let
|
0