async/await ва fetch
Ин барои чӣ лозим аст
Промисҳо «дӯзахи callback-ҳо»-ро ҳал карданд, вале занҷирҳои then нисбат ба коди оддӣ бадтар хонда
мешаванд. Калимаҳои калидии async ва await имкон медиҳанд, ки коди асинхрониро гӯё синхронӣ
нависем: аз боло ба поён, бо тағйирёбандаҳои оддӣ ва try … catch-и оддӣ.
fetch бошад — он чизест, ки ҳамааш барои он сар шуда буд: дархостҳо ба сервер. Ҳар сайте, ки обу
ҳаво, навори хабарҳо, молҳо ё паёмҳоро нишон медиҳад, онҳоро тавассути дархостҳо мегирад. Дар React
додаҳо маҳз ҳамин тавр бор мешаванд: useEffect + fetch + await.
Функсияи async
Калимаи async пеш аз функсия ду кор мекунад:
- функсия ҳамеша промис бармегардонад:
return 5ба промис бо қимати5табдил меёбад; - дар дохил
awaitнавиштан мумкин аст.
async function getNumber() {
return 5;
}
const p = getNumber();
console.log(p instanceof Promise);
p.then((value) => console.log(value));
Натиҷа:
true
5
Функсияҳои тирчадор ҳам асинхронӣ мешаванд: const load = async (id) => { ... };
await — промисро интизор шудан
await промис ҳамин функсия-ро то иҷро шудани промис бозмедорад ва қимати онро бармегардонад:
const wait = (ms, value) => new Promise((resolve) => setTimeout(() => resolve(value), ms));
async function main() {
console.log("Сар кардем");
const name = await wait(100, "Аня"); // 100 мс интизор мешавем
const city = await wait(100, "Душанбе"); // боз 100 мс
console.log(name + " аз шаҳри " + city);
}
main();
console.log("main оғоз шуд, вале ҳоло тамом нашудааст");
Натиҷа:
Сар кардем
main оғоз шуд, вале ҳоло тамом нашудааст
Аня аз шаҳри Душанбе
Муҳим: await тамоми барномаро қатъ намекунад. Вай танҳо функсияи async-и худро таваққуф медиҳад, ва
коди боқимонда идома меёбад. Барои ҳамин сатри дуюм пеш аз сатри сеюм чоп шуд.
Ин ҳамон коди занҷири then аст, танҳо дигар хел навишта шудааст: ҳама чиз баъд аз await — гӯё дар дохили then.
Хатоҳо: try … catch
Агар промиси зери await рад шавад, await хаторо мепартояд, мисли throw. Онро бо try … catch-и
оддӣ медоранд:
const fail = () => new Promise((_, reject) => setTimeout(() => reject(new Error("сервер дастнорас аст")), 50));
async function main() {
try {
await fail();
console.log("ба ин ҷо намерасем");
} catch (err) {
console.log("Хато: " + err.message);
} finally {
console.log("Боркунӣ тамом шуд");
}
}
main();
Натиҷа:
Хато: сервер дастнорас аст
Боркунӣ тамом шуд
Пай дар пай ё параллелӣ
Ду await паси ҳам пай дар пай иҷро мешаванд: дархости дуюм танҳо вақте сар мешавад, ки аввалӣ
тамом шуд. Агар дархостҳо аз ҳамдигар вобаста набошанд, ин интизории зиёдатӣ аст. Онҳоро якбора оғоз
кунед ва бо Promise.all якҷоя интизор шавед:
const wait = (ms, value) => new Promise((resolve) => setTimeout(() => resolve(value), ms));
async function sequential() {
const a = await wait(100, "A");
const b = await wait(100, "B");
return [a, b];
}
async function parallel() {
const [a, b] = await Promise.all([wait(100, "A"), wait(100, "B")]);
return [a, b];
}
async function main() {
let start = Date.now();
await sequential();
console.log("Пай дар пай зиёда аз 190 мс: " + (Date.now() - start >= 190));
start = Date.now();
await parallel();
console.log("Параллелӣ камтар аз 190 мс: " + (Date.now() - start < 190));
}
main();
Натиҷа:
Пай дар пай зиёда аз 190 мс: true
Параллелӣ камтар аз 190 мс: true
Қоида: агар ба қадами навбатӣ натиҷаи қадами пешина лозим бошад — await пай дар пай. Агар не — Promise.all.
await дар давра
for (const id of ids) {
const user = await loadUser(id); // пай дар пай: ҳар кадом пешинаро интизор мешавад
}
const users = await Promise.all(ids.map((id) => loadUser(id))); // ҳама якбора
Аммо ids.forEach(async (id) => { await ... }) — дом аст: forEach callback-ҳои асинхрониро интизор
намешавад, ва коди баъд аз он пеш аз тамом шудани боркуниҳо иҷро мешавад.
fetch — дархост ба сервер
fetch(суроға) дархости HTTP мефиристад ва промиси ҷавоб (Response)-ро бармегардонад. Бадани ҷавоб
алоҳида ва ҳам асинхронӣ хонда мешавад — барои ҳамин await ду бор:
async function loadTodo() {
const response = await fetch("https://jsonplaceholder.typicode.com/todos/1");
console.log(response.status); // 200 — рамзи ҷавоб
console.log(response.ok); // true, агар рамз 200–299 бошад
const todo = await response.json(); // бадани ҷавоб: JSON → объект
console.log(todo.title);
}
loadTodo();
Натиҷа тақрибан чунин аст (ин сервери воқеии таълимӣ аст):
200
true
delectus aut autem
Ҷавоб чӣ дорад:
| Хосият / усул | Чӣ медиҳад |
|---|---|
response.status |
рамзи ҷавоб: 200, 201, 404, 500… |
response.ok |
true, агар рамз аз 200 то 299 бошад |
await response.json() |
бадан, аз JSON таҳлилшуда |
await response.text() |
бадан ҳамчун сатр |
response.headers.get("Content-Type") |
сарлавҳаи ҷавоб |
Рамзҳое, ки бештар вомехӯранд: 200 — ҳама хуб, 201 — сохта шуд, 400 — дархости нодуруст, 401 /
403 — дастрасӣ нест, 404 — ёфт нашуд, 500 — хато дар сервер.
Хатои шабака ва хатои сервер — чизҳои гуногунанд
fetch промисро танҳо вақте рад мекунад, ки ҷавоб тамоман нест: интернет нест, сервер дастнорас аст,
суроға нодуруст аст. Ҷавоби 404 ё 500 — ин ҷавоби бомуваффақият гирифташуда бо рамзи бад аст. Онро
худатон санҷидан лозим:
async function loadJSON(url) {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return response.json();
}
Бе санҷиши response.ok барнома кӯшиш мекунад, ки саҳифаи хаторо ҳамчун додаҳо таҳлил кунад.
Фиристодани додаҳо: POST
Барои фиристодани додаҳо (сохтани вазифа, ворид шудан, гузоштани шарҳ) ҳамчун аргументи дуюм танзимоти дархостро медиҳанд:
async function addComment(text) {
const response = await fetch("https://api.example.com/comments", {
method: "POST", // пешфарз GET
headers: { "Content-Type": "application/json" }, // ба сервер мегӯем: дар бадан JSON
body: JSON.stringify({ text }), // бадан — сатр
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json(); // сервер одатан объекти сохташударо мефиристад
}
Усулҳои асосии HTTP: GET — гирифтан, POST — сохтан, PUT / PATCH — тағйир додан, DELETE — нест
кардан. Якҷоя онҳо REST API-ро ташкил медиҳанд — аксари серверҳое, ки шумо бо онҳо кор мекунед, ҳамин
тавр сохта шудаанд.
Боркунии маъмулии додаҳо
Ин қолабест, ки дар ҳар барнома вомехӯрад — аз ҷумла дар React. Боркунӣ се ҳолат дорад: меравад, шуд, хато:
async function showUsers() {
console.log("Боркунӣ...");
try {
const users = await loadJSON("https://jsonplaceholder.typicode.com/users");
console.log("Корбарон: " + users.length);
} catch (err) {
console.log("Бор кардан нашуд: " + err.message);
} finally {
console.log("Нишондиҳандаи боркуниро пинҳон мекунем");
}
}
Дар React ин се ҳолат се тағйирёбандаи ҳолат мешаванд: loading, data ва error.
Дар дохил чӣ гуна кор мекунад
async/await — ин «шакари синтаксисӣ» бар промисҳост. Ба await дучор шуда, муҳаррик ҷои истодани
функсияро дар хотир нигоҳ медорад ва аз он мебарояд, промис баргардонда. Коди боқимонда кор карданро
идома медиҳад. Вақте промиси интизоршаванда иҷро шуд, давомаи функсия ба навбати микровазифаҳо гузошта
мешавад ва аз ҳамон ҷо, бо ҳамон тағйирёбандаҳо иҷро мешавад.
fetch худи дархостро бо қувваи браузер ё Node.js — берун аз JavaScript иҷро мекунад. Дар браузер маҳдудияти
CORS ҳаст: саҳифа ҷавобҳои сервери бегонаро танҳо вақте хонда метавонад, ки он сервер инро бо сарлавҳаҳои
махсус иҷозат дода бошад. Барои ҳамин баъзан дархосте, ки дар Node.js кор мекунад, дар браузер хато медиҳад.
Хатоҳои маъмул
await-и фаромӯшшуда.const user = fetch(url);— дарuserпромис аст, на ҷавоб.response.json()беawaitҳам промис аст, на додаҳо.awaitберун аз функсияиasync. Дар функсияи оддӣawaitхатои синтаксисӣ аст. (Дар модулҳо ва дар вазифаҳои ин курсawaitдар сатҳи боло ҳам иҷозат аст.)- Санҷиши
response.okнест. Ҷавоби 404 худ аз худ баcatchнамеафтад. - Пайдарпайии зиёдатӣ. Дархостҳои мустақил бо
awaitпаси ҳам — суст аст.Promise.all-ро истифода баред. forEachбоasync. Интизор намешавад.for … ofёPromise.allбоmap-ро истифода баред.JSON.stringifyбароиbodyфаромӯш шуд. Объектро мустақим додан мумкин нест — дар бадан танҳо сатр.
Ёддошт
| Чӣ | Чӣ тавр |
|---|---|
| Функсияи асинхронӣ | async function f() { ... }, async () => { ... } |
| Интизор шудан | const x = await promise; |
| Хато | try { await ... } catch (err) { ... } |
| Параллелӣ | const [a, b] = await Promise.all([p1, p2]); |
| GET | const res = await fetch(url); const data = await res.json(); |
| Санҷиш | if (!res.ok) throw new Error(HTTP ${res.status}); |
| POST | fetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(obj) }) |