Autor Zpráva
benett
Profil
Mám funkci, uvnitř které zpracovávám JSON soubor. Jak docílit toho, aby se počkalo na zpracování? Vypadá to na použití deferred, ale jak to udělat?
function f(param) {
  var ret = NULL;
  $.getJSON('http://www.neco.cz/data.json', function(data) {
    if(data['val'] > param) ret = 25;
  });
  return ret;
}
Keeehi
Profil
getJSON bude jen nějaký obal prostého AJAXu (asynchronního). U getJSON() to asi nepůjde, ale metoda ajax() jde nastavit tak, aby byla synchronní. Stačí mji předat async: false.
Ovšem už to je označené za zastaralé a nové verze prohlížečů by to měly přestávat podporovat.
Mnohem lepší řešení bude, když kód předěláš tak, aby počítal s tou asynchronností.
_es
Profil
benett [#1]:
A prečo jednoducho nedáš všetok kód, čo má pracovať s vrátenými dátami, do funkcie function(data) {...}? (Alebo zavoláš v tej funkcii iné funkcie s tými dátami pracujúce.)
juriad
Profil
benett:
Při tom čekání by se musela zastavit interpretace JS a protože pohyb myši, scrollování atp. generuje JS události, musí se zastavit interakce se stránkou. Tobě se to bude jevit jako, že se stránka sekla. Na pomalém nestabilním připojení třeba v metru nebo ve vlaku může požadavek trvat minuty.

Toto je důvod, proč se vnější funkce nemůže čekat na tu vnitřní. Kdykoli používáš AJAX počítej s tím, že ti odpověď přijde v ten nejneočekávanější okamžik (většinou to znamená "za dlouho").

Porovnej tyto dvě funkce; je doufám zřejmé, jak se bude chovat ta druhá a proč nechceš čekat na tu vnitřní funkci.
function f() {
  var ret = NULL;
  $.getJSON('http://www.neco.cz/data.json', function() {
    ret = 25;
  });
  return ret;
}

function g() {
  var ret = NULL;
  window.setTimeout(function() {
    ret = 25;
  }, 1000);
  return ret;
}
benett
Profil
_es:
Jak myslíš tu část před závorkou? Případně mohl bys ten kód napsat?
Radek9
Profil
benett:
Nauč se pracovat s promise objektem (v jQuery deferred), který vrací funkce $.getJSON. Promise má metodu then, která přijímá handler, který dostane data po dokončení asynchronní operace. Sama ta metoda navíc vrací další promise, který v sobě bude obsahovat data, která vrátí onen handler.
function f(param) {
  return $.getJSON('http://www.neco.cz/data.json')
    .then(function (data) {
      if(data.val > param) return 25
      return null
    })
}

f(10).then(function (val) {
  console.log(val) // To bude buď 25, nebo null
})

Tedy funkce nevrací přímo data, ale jakousi jejich budoucí reprezentaci, ze které je někdy (nevíš přesně kdy) dostaneš.

Celé tohle se dá v nové verzi JS (ES2016) zapsat docela elegantně pomocí asynchronních funkcí:
async function f(param) {
  const data = await $.getJSON('http://www.neco.cz/data.json')
  if (data.val > param) return 25
  return null
}

(async function () {
  const val = await f(10)
  console.log(val)
})()

Mrkni na Babel, dost si ulehčíš život.
benett
Profil
Radek9:
Díky moc! Skvělá odpověď
_es
Profil
benett:
Jak myslíš tu část před závorkou?
Myslím v [#1] function(data) {Tu dáš všetok kód, čo nejako pracuje s premennou data}.
V tom kóde môžeš samozrejme aj volať iné funkcie, ktoré premennú data nejako spracujú.

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: