request(options)
Áttekintés
XHR (más néven AJAX) kéréseket küld, és egy promise-t ad vissza.
m.request({
method: 'PUT',
url: '/api/v1/users/:id',
params: { id: 1 },
body: { name: 'test' },
}).then(function (result) {
console.log(result);
});
Aláírás
promise = m.request(options)
Paraméter | Típus | Kötelező | Leírás |
---|---|---|---|
options | Object | Igen | A kéréshez tartozó beállítások. |
options.method | String | Nem | A használandó HTTP metódus. Lehetséges értékei: GET , POST , PUT , PATCH , DELETE , HEAD vagy OPTIONS . Alapértelmezett értéke: GET . |
options.url | String | Igen | Az az útvonalnév, amelyre a kérést el kell küldeni, opcionálisan interpolálva az options.params értékeivel. |
options.params | Object | Nem | Az URL-be interpolálandó és/vagy a lekérdezési karakterláncba szerializálandó adatok. |
options.body | Object | Nem | A kérés törzsébe szerializálandó adatok (nem-GET kérések esetén). |
options.async | Boolean | Nem | Meghatározza, hogy a kérés aszinkron legyen-e. Alapértelmezett értéke: true . |
options.user | String | Nem | Felhasználónév a HTTP hitelesítéshez. Alapértelmezett értéke: undefined . |
options.password | String | Nem | Jelszó a HTTP hitelesítéshez. Alapértelmezett értéke: undefined . Ez az opció a XMLHttpRequest kompatibilitása miatt érhető el, mivel a jelszót titkosítatlanul küldi el a hálózaton, ezért kerülje a használatát. |
options.withCredentials | Boolean | Nem | Meghatározza, hogy a cookie-kat harmadik féltől származó domaineknek küldje-e. Alapértelmezett értéke: false . |
options.timeout | Number | Nem | Az az időtartam milliszekundumban, ameddig egy kérés eltarthat, mielőtt automatikusan megszakad. Alapértelmezett értéke: undefined . |
options.responseType | String | Nem | A válasz várható típusa. Alapértelmezett értéke: "" , ha az extract definiálva van, "json" , ha hiányzik. Ha responseType: "json" , akkor belsőleg végrehajtja a JSON.parse(responseText) parancsot. |
options.config | xhr = Function(xhr) | Nem | Elérhetővé teszi a mögöttes XMLHttpRequest objektumot alacsony szintű konfiguráláshoz és opcionális cseréhez (egy új XHR visszaadásával). |
options.headers | Object | Nem | A kéréshez hozzáfűzendő fejlécek a küldés előtt (közvetlenül az options.config előtt alkalmazva). |
options.type | any = Function(any) | Nem | Konstruktor, amely a válaszban szereplő minden objektumra alkalmazásra kerül. Alapértelmezett értéke az identitásfüggvény. |
options.serialize | string = Function(any) | Nem | Szerializálási módszer, amely a body -ra alkalmazandó. Alapértelmezett értéke JSON.stringify , vagy ha az options.body a FormData vagy URLSearchParams egy példánya, akkor az identitásfüggvény (azaz function(value) {return value} ). |
options.deserialize | any = Function(any) | Nem | Deszerializálási módszer, amely az xhr.response -ra vagy a normalizált xhr.responseText -re alkalmazandó. Alapértelmezett értéke az identitásfüggvény. Ha az extract definiálva van, a deserialize figyelmen kívül lesz hagyva. |
options.extract | any = Function(xhr, options) | Nem | Egy hook, amely meghatározza, hogyan kell a XMLHttpRequest választ olvasni. Hasznos a válaszadatok feldolgozásához, a fejlécek és a cookie-k olvasásához. Alapértelmezett értéke egy olyan függvény, amely visszaadja az options.deserialize(parsedResponse) értéket, és kivételt dob, ha a szerver válaszkódja hibát jelez, vagy ha a válasz szintaktikailag érvénytelen. Ha egyéni extract visszahívás van megadva, az xhr paraméter a kéréshez használt XMLHttpRequest példány, az options pedig az az objektum, amelyet az m.request hívásnak adtak át. Továbbá, a deserialize figyelmen kívül lesz hagyva, és az extract visszahívás által visszaadott érték változatlanul lesz felhasználva, amikor a promise feloldódik. |
options.background | Boolean | Nem | Ha false , a kérés befejezésekor újrarajzolja a csatolt komponenseket. Ha true , akkor nem rajzolja újra. |
returns | Promise | Egy promise, amely a válaszadatokra oldódik fel, miután az extract , deserialize és type metódusokon áthaladtak. Ha a válaszkód hibát jelez, a promise el fog utasulni, de ez megakadályozható az extract opció beállításával. |
promise = m.request(url, options)
Paraméter | Típus | Kötelező | Leírás |
---|---|---|---|
url | String | Igen | Az az útvonalnév, amelyre a kérést el kell küldeni. Az options.url felülírja ezt, ha jelen van. |
options | Object | Nem | A kéréshez tartozó beállítások. |
returns | Promise | Egy promise, amely a válaszadatokra oldódik fel, miután az extract , deserialize és type metódusokon áthaladtak. |
Ez a második forma nagyrészt egyenértékű az m.request(Object.assign({url: url}, options))
-szel, anélkül, hogy belsőleg függene az ES6 globális Object.assign
függvényétől.
Hogyan kell olvasni a szignatúrákat
Hogyan működik
Az m.request
segédeszköz egy vékony burkolat a XMLHttpRequest
körül, és lehetővé teszi HTTP kérések küldését távoli szerverekre adatok mentéséhez és/vagy lekéréséhez egy adatbázisból.
m.request({
method: 'GET',
url: '/api/v1/users',
}).then(function (users) {
console.log(users);
});
Az m.request
hívása egy promise-t ad vissza, és a promise láncának befejezésekor elindít egy újrarajzolást.
Alapértelmezés szerint az m.request
feltételezi, hogy a válasz JSON formátumban van, és JavaScript objektummá (vagy tömbé) alakítja.
Ha a HTTP válaszkód hibát jelez, a visszaadott Promise el fog utasulni. Az extract visszahívás megadásával elkerülhető a promise elutasítása.
Tipikus használati esetek
Íme egy illusztratív példa egy olyan komponensre, amely az m.request
segítségével kér le adatokat egy szerverről.
var Data = {
todos: {
list: [],
fetch: function () {
m.request({
method: 'GET',
url: '/api/v1/todos',
}).then(function (items) {
Data.todos.list = items;
});
},
},
};
var Todos = {
oninit: Data.todos.fetch,
view: function (vnode) {
return Data.todos.list.map(function (item) {
return m('div', item.title);
});
},
};
m.route(document.body, '/', {
'/': Todos,
});
Tegyük fel, hogy a /api/items
szerver URL-re irányuló kérés JSON formátumban ad vissza egy objektumtömböt.
Amikor az m.route
meghívásra kerül az alján, a Todos
komponens inicializálódik. Az oninit
meghívásra kerül, amely meghívja az m.request
-et. Ez aszinkron módon lekér egy objektumtömböt a szerverről. Az "aszinkron" azt jelenti, hogy a JavaScript továbbra is futtat más kódot, miközben a szerver válaszára vár. Ebben az esetben ez azt jelenti, hogy a fetch
visszatér, és a komponens az eredeti üres tömböt használva kerül renderelésre Data.todos.list
-ként. A szerverre irányuló kérés befejeződése után az items
objektumtömb hozzárendelődik a Data.todos.list
változóhoz. Ezt követően a komponens újra renderelésre kerül, ami egy listát eredményez a <div>
elemekből, amelyek az egyes todo
elemek címeit tartalmazzák.
Hiba kezelés
Amennyiben egy nem-file:
kérés a 2xx vagy 304-es státuszkódtól eltérő kóddal tér vissza, hibával kerül elutasításra. Ez a hiba egy normál Error példány, de néhány speciális tulajdonsággal rendelkezik.
- Az
error.message
a nyers válaszszövegre van beállítva. - Az
error.code
magára az állapotkódra van beállítva. - Az
error.response
az elemzett válaszra van beállítva, azoptions.extract
és azoptions.deserialize
használatával, ahogyan a normál válaszoknál is.
Ez sok esetben hasznos, amikor maguk a hibák olyan dolgok, amelyekkel számolni lehet. Ha észlelni szeretné, hogy egy munkamenet lejárt-e - megteheti if (error.code === 401) return promptForAuth().then(retry)
. Ha eléri egy API szabályozási mechanizmusát, és az egy hibát adott vissza egy "timeout": 1000
-rel, akkor használhatja a setTimeout(retry, error.response.timeout)
függvényt.
Betöltési ikonok és hibaüzenetek kezelése
Íme a fenti példa egy kibővített változata, amely egy betöltési indikátort és egy hibaüzenetet valósít meg:
var Data = {
todos: {
list: null,
error: '',
fetch: function () {
m.request({
method: 'GET',
url: '/api/v1/todos',
})
.then(function (items) {
Data.todos.list = items;
})
.catch(function (e) {
Data.todos.error = e.message;
});
},
},
};
var Todos = {
oninit: Data.todos.fetch,
view: function (vnode) {
return Data.todos.error
? [m('.error', Data.todos.error)]
: Data.todos.list
? [
Data.todos.list.map(function (item) {
return m('div', item.title);
}),
]
: m('.loading-icon');
},
};
m.route(document.body, '/', {
'/': Todos,
});
Van néhány különbség ebben a példában és az előzőben. Itt a Data.todos.list
az elején null
. Ezenkívül van egy extra error
mező a hibaüzenet tárolására, továbbá a Todos
komponens nézete módosítva lett: hibaüzenetet jelenít meg, ha van ilyen, egyébként betöltési ikont, amennyiben a Data.todos.list
nem tömb.
Dinamikus URL-ek
A kérés URL-jei tartalmazhatnak interpolációkat:
m.request({
method: 'GET',
url: '/api/v1/users/:id',
params: { id: 123 },
}).then(function (user) {
console.log(user.id); // 123 naplózása
});
A fenti kódban a :id
a params
objektumból származó adatokkal van feltöltve, így a kérés GET /api/v1/users/123
formát ölti.
Az interpolációk figyelmen kívül maradnak, ha a params
tulajdonságban nem található egyező adat.
m.request({
method: 'GET',
url: '/api/v1/users/foo:bar',
params: { id: 123 },
});
A fenti kódban a kérés GET /api/v1/users/foo:bar?id=123
lesz.
Kérések megszakítása
Néha kívánatos egy kérés megszakítása. Például egy automatikus kiegészítő/előrejelző widgetben biztosítani szeretné, hogy csak az utolsó kérés fejeződjön be, mert az automatikus kiegészítők általában több kérést indítanak el, amikor a felhasználó gépel, és a HTTP kérések a hálózatok kiszámíthatatlan jellege miatt sorrendben befejeződhetnek. Ha egy másik kérés az utolsó elindított kérés után fejeződik be, a widget kevésbé releváns (vagy potenciálisan helytelen) adatokat jelenítene meg, mintha az utolsó elindított kérés fejeződött volna be utoljára.
Az m.request()
az options.config
paraméteren keresztül elérhetővé teszi a mögöttes XMLHttpRequest
objektumot, amely lehetővé teszi az objektumra való hivatkozás mentését, és szükség esetén annak abort
metódusának meghívását:
var searchXHR = null;
function search() {
abortPreviousSearch();
m.request({
method: 'GET',
url: '/api/v1/users',
params: { search: query },
config: function (xhr) {
searchXHR = xhr;
},
});
}
function abortPreviousSearch() {
if (searchXHR !== null) searchXHR.abort();
searchXHR = null;
}
Fájlfeltöltés
Fájlok feltöltéséhez először hivatkozást kell szereznie egy File
objektumra. Ez legegyszerűbben egy <input type="file">
elemmel érhető el.
m.render(document.body, [m('input[type=file]', { onchange: upload })]);
function upload(e) {
var file = e.target.files[0];
}
A fenti kódrészlet egy fájlfeltöltő mezőt renderel. Ha egy felhasználó kiválaszt egy fájlt, az onchange
esemény aktiválódik, amely meghívja az upload
függvényt. Az e.target.files
egy File
objektumok listája.
Ezután létre kell hoznia egy FormData
objektumot egy multipart kérés létrehozásához, amely egy speciálisan formázott HTTP kérés, amely fájladatok küldésére alkalmas a kérés törzsében.
function upload(e) {
var file = e.target.files[0];
var body = new FormData();
body.append('myfile', file);
}
Ezután meg kell hívnia az m.request
-et, és az options.method
-ot egy olyan HTTP metódusra kell állítania, amely törzset használ (pl. POST
, PUT
, PATCH
), és a FormData
objektumot kell használnia options.body
-ként.
function upload(e) {
var file = e.target.files[0];
var body = new FormData();
body.append('myfile', file);
m.request({
method: 'POST',
url: '/api/v1/upload',
body: body,
});
}
Feltételezve, hogy a szerver konfigurálva van a multipart kérések fogadására, a fájlinformációk a myfile
kulccsal lesznek elérhetők.
Több fájl feltöltése
Lehetséges több fájlt feltölteni egyetlen kérésben. Ezáltal a kötegelt feltöltés atomi lesz, azaz egyetlen fájl sem lesz feldolgozva, ha hiba történik a feltöltés során, ezáltal nem lehetséges a fájlok részleges mentése. Ha a lehető legtöbb fájlt szeretné menteni hálózati hiba esetén, fontolja meg, hogy minden fájlt külön kérésben tölt fel.
Több fájl feltöltéséhez egyszerűen fűzze hozzá mindet a FormData
objektumhoz. Fájlfeltöltő mező használatakor a fájlok listája a multiple
attribútum hozzáadásával szerezhető be:
m.render(document.body, [
m('input[type=file][multiple]', { onchange: upload }),
]);
function upload(e) {
var files = e.target.files;
var body = new FormData();
for (var i = 0; i < files.length; i++) {
body.append('file' + i, files[i]);
}
m.request({
method: 'POST',
url: '/api/v1/upload',
body: body,
});
}
Folyamat figyelése
Néha, ha egy kérés eleve lassú (pl. egy nagy fájl feltöltése), kívánatos egy folyamatjelző megjelenítése a felhasználónak, jelezve, hogy az alkalmazás még mindig működik.
Az m.request()
az options.config
paraméteren keresztül elérhetővé teszi a mögöttes XMLHttpRequest
objektumot, amely lehetővé teszi eseményfigyelők csatolását a XMLHttpRequest objektumhoz.
var progress = 0;
m.mount(document.body, {
view: function () {
return [
m('input[type=file]', { onchange: upload }),
progress + '% completed',
];
},
});
function upload(e) {
var file = e.target.files[0];
var body = new FormData();
body.append('myfile', file);
m.request({
method: 'POST',
url: '/api/v1/upload',
body: body,
config: function (xhr) {
xhr.upload.addEventListener('progress', function (e) {
progress = e.loaded / e.total;
m.redraw(); // mondja meg a Mithril.js-nek, hogy az adatok megváltoztak, és újrarajzolásra van szükség
});
},
});
}
A fenti példában egy fájlbevitel kerül renderelésre. Ha a felhasználó kiválaszt egy fájlt, egy feltöltés indul el, és a config
visszahívásban egy progress
eseménykezelő kerül regisztrálásra. Ez az eseménykezelő akkor aktiválódik, amikor a XMLHttpRequest-ben folyamatfrissítés történik. Mivel a XMLHttpRequest folyamateseményét a Mithril.js virtuális DOM motorja nem kezeli közvetlenül, az m.redraw()
-ot meg kell hívni, hogy a Mithril.js számára jelezve legyen, hogy az adatok megváltoztak, és újrarajzolás szükséges.
Válasz típusra konvertálása
Az általános alkalmazásarchitektúrától függően kívánatos lehet egy kérés válaszadatait egy adott osztályba vagy típusba konvertálni (például a dátummezők egységes elemzéséhez, vagy segítő metódusok használatához).
Átadhat egy konstruktort az options.type
paraméterként, a Mithril.js pedig példányosítani fogja azt a HTTP válaszban szereplő minden objektumra.
function User(data) {
this.name = data.firstName + ' ' + data.lastName;
}
m.request({
method: 'GET',
url: '/api/v1/users',
type: User,
}).then(function (users) {
console.log(users[0].name); // egy név naplózása
});
A fenti példában, feltételezve, hogy a /api/v1/users
egy objektumtömböt ad vissza, a User
konstruktor példányosítva lesz (azaz new User(data)
-ként lesz meghívva) a tömb minden objektumához. Amennyiben a válasz egyetlen objektumot ad vissza, az az objektum kerül felhasználásra body
argumentumként.
Nem-JSON válaszok
Néha egy szerver végpont nem ad vissza JSON választ: például kérhet egy HTML fájlt, egy SVG fájlt vagy egy CSV fájlt. Alapértelmezés szerint a Mithril.js megpróbálja elemezni a választ, mintha JSON lenne. A viselkedés felülbírálásához definiáljon egy egyéni options.deserialize
függvényt.
m.request({
method: 'GET',
url: '/files/icon.svg',
deserialize: function (value) {
return value;
},
}).then(function (svg) {
m.render(document.body, m.trust(svg));
});
A fenti példában a kérés lekér egy SVG fájlt, nem tesz semmit az elemzéséhez (mert a deserialize
egyszerűen visszaadja az értéket változatlanul), majd az SVG karakterlánc megbízható HTML-ként kerül renderelésre.
Természetesen egy deserialize
függvény bonyolultabb is lehet:
m.request({
method: 'GET',
url: '/files/data.csv',
deserialize: parseCSV,
}).then(function (data) {
console.log(data);
});
function parseCSV(data) {
// naiv implementáció a példa egyszerűsége kedvéért
return data.split('\n').map(function (row) {
return row.split(',');
});
}
Eltekintve attól a ténytől, hogy a fenti parseCSV függvény nem kezel sok olyan esetet, amelyet egy megfelelő CSV elemző kezelne, a fenti kód tömbök egy tömbjét naplózza.
Egyéni fejlécek is hasznosak lehetnek ebben a tekintetben. Például, ha SVG-t kér, valószínűleg be szeretné állítani a tartalomtípust ennek megfelelően. Az alapértelmezett JSON kéréstípus felülbírálásához állítsa az options.headers
-t egy kulcs-érték párok objektumára, amelyek a kérésfejléc neveinek és értékeinek felelnek meg.
m.request({
method: 'GET',
url: '/files/image.svg',
headers: {
'Content-Type': 'image/svg+xml; charset=utf-8',
Accept: 'image/svg, text/*',
},
deserialize: function (value) {
return value;
},
});
Válasz részleteinek lekérése
Hasznos lehet a szerver válaszának részletesebb vizsgálata és manuális feldolgozása. Ez egy egyéni options.extract
függvény átadásával valósítható meg.
m.request({
method: 'GET',
url: '/api/v1/users',
extract: function (xhr) {
return { status: xhr.status, body: xhr.responseText };
},
}).then(function (response) {
console.log(response.status, response.body);
});
Az options.extract
paramétere a XMLHttpRequest objektum, miután a művelet befejeződött, de mielőtt átadták volna a visszaadott promise láncnak, ezáltal a promise még elutasított állapotba kerülhet, amennyiben a feldolgozás során kivétel keletkezik.
Lekérdezések kiadása IP címekre
Az URL-ekben a paraméterek detektálása leegyszerűsített módon történik. Emiatt az IPv6 címek szegmensei útvonalparaméter interpolációként értelmeződnek. Mivel az útvonalparaméterek helyes interpolálásához elválasztójelre van szükség, ez hibát okoz.
// Ez nem működik
m.request('http://[2001:db8::990a:cd27:4d9e:79]:8080/some/path', {
// ...
});
A probléma megoldásához az IPv6 címet és a portot paraméterként kell átadni.
m.request('http://:host/some/path', {
params: { host: '[2001:db8::990a:cd27:4d9e:79]:8080' },
// ...
});
Ez nem probléma az IPv4 címekkel, és azokat normálisan használhatja.
// Ez a várt módon fog működni
m.request('http://192.0.2.15:8080/some/path', {
// ...
});
Miért JSON a HTML helyett
Sok szerveroldali keretrendszer biztosít egy nézetmotort, amely a HTML kiszolgálása előtt (oldalbetöltéskor vagy AJAX-on keresztül) adatbázisadatokat interpolál egy sablonba, majd a jQuery segítségével kezeli a felhasználói interakciókat.
Ezzel szemben a Mithril.js egy vastag kliensalkalmazásokhoz tervezett keretrendszer, amely jellemzően külön tölti le a sablonokat és az adatokat, és JavaScripten keresztül kombinálja azokat a böngészőben. A sablonozás nagy részének a böngészőben történő elvégzése olyan előnyökkel járhat, mint a szervererőforrások felszabadításával járó működési költségek csökkentése. A sablonok és az adatok elkülönítése lehetővé teszi a sablonkód hatékonyabb gyorsítótárazását, és jobb kód újrafelhasználást tesz lehetővé a különböző típusú kliensek között (pl. asztali, mobil). Egy másik előny, hogy a Mithril.js lehetővé teszi a megtartott módú felhasználói felület fejlesztési paradigmát, amely jelentősen leegyszerűsíti az összetett felhasználói interakciók fejlesztését és karbantartását.
Egy tipikus Mithril.js alkalmazásban ezt a JSON formátumú adatot általában egy nézet használja fel.
Kerülje a szerver által generált dinamikus HTML renderelését a Mithril segítségével. Ha van egy meglévő alkalmazása, amely szerveroldali sablonozó rendszert használ, és szeretné újraarchitektúrázni, először döntse el, hogy a törekvés egyáltalán megvalósítható-e. A vastag szerverarchitektúráról a vastag kliensarchitektúrára való áttelepítés általában egy meglehetősen nagy erőfeszítés, amely magában foglalja a logika sablonokból logikai adatszolgáltatásokba történő áthelyezését (és az ezzel járó tesztelést).
A fetch()
egy újabb Web API az erőforrások szerverekről történő lekérésére, amely a XMLHttpRequest
-hez hasonlóan az erőforrások szerverekről történő lekérésére szolgál.
A Mithril.js m.request
számos okból a XMLHttpRequest
-et használja a fetch()
helyett:
- A
fetch
még nincs teljesen szabványosítva, és a specifikáció változásainak lehet kitéve. - A
XMLHttpRequest
hívások megszakíthatók a feloldásuk előtt (pl. a versenyhelyzetek elkerülése érdekében az azonnali keresési felhasználói felületeken). - A
XMLHttpRequest
hookokat biztosít a hosszú ideig futó kérésekhez (pl. fájlfeltöltések). - A
XMLHttpRequest
minden böngésző által támogatott, míg afetch()
nem támogatott az Internet Explorer és a régebbi (5.0 Lollipop előtti) Android verziókban.
Jelenleg a böngésző támogatásának hiánya miatt a fetch()
általában egy polyfill -et igényel, amely tömörítetlenül több mint 11 KB, ami közel háromszor nagyobb, mint a Mithril.js XHR modulja.
Annak ellenére, hogy sokkal kisebb, a Mithril.js XHR modulja számos fontos és nem olyan triviális megvalósítású funkciót támogat, mint az URL interpoláció és a lekérdezési karakterlánc szerializálása, amellett, hogy zökkenőmentesen integrálódik a Mithril.js automatikus újrarajzoló alrendszerébe. A fetch
polyfill nem támogatja ezeket, ezekhez extra könyvtárak és boilerplate kód szükséges a funkcionalitás eléréséhez.
Ezenkívül a Mithril.js XHR modulja a JSON-alapú végpontokra van optimalizálva, és a leggyakoribb esetet megfelelően tömörré teszi - azaz m.request(url)
- míg a fetch
egy további lépést igényel a válaszadatok JSON formátumba történő elemzéséhez: fetch(url).then(function(response) {return response.json()}
A fetch()
API-nak van néhány technikai előnye a XMLHttpRequest
-hez képest néhány ritka esetben:
- streaming API-t biztosít (a "videó streaming" értelemben, nem a reaktív programozás értelemben), amely jobb késleltetést és memóriahasználatot tesz lehetővé nagyon nagy válaszok esetén (a kód összetettségének rovására).
- integrálódik a Service Worker API -ba, amely extra vezérlőréteget biztosít a hálózati kérések hogyan és mikor történő végrehajtása felett. Ez az API hozzáférést biztosít a push értesítésekhez és a háttérszinkronizálási funkciókhoz is.
Tipikus esetekben a streaming nem biztosít észrevehető teljesítménynövekedést, mert általában nem tanácsos eleve megabájtnyi adatot letölteni. Ezenkívül a kis pufferek ismételt felhasználásából származó memórianyereség kiegyenlíthető vagy érvényteleníthető, ha túlzott böngésző újrarajzolást eredményeznek. Ezért a fetch()
streaming választása az m.request
helyett csak rendkívül erőforrásigényes alkalmazásokhoz ajánlott.
Kerüld a rossz gyakorlatokat
A Promise nem a válasz adat
Az m.request
metódus egy Promise
-t ad vissza, nem magát a válasz adatot. Nem tudja közvetlenül visszaadni ezt az adatot, mert egy HTTP kérés teljesítése hosszú időt vehet igénybe (a hálózati késleltetés miatt), és ha a JavaScript várna rá, az lefagyasztaná az alkalmazást addig, amíg az adat elérhetővé nem válik.
// KERÜLD
var users = m.request('/api/v1/users');
console.log('felhasználók listája:', users);
// A `users` NEM a felhasználók listája, hanem egy Promise
// INKÁBB
m.request('/api/v1/users').then(function (users) {
console.log('felhasználók listája:', users);
});