I-app yakho iyahlaziywa. Uyazi i-backend enikeza izinto ezithakazelisayo bese ufakele idatha nge-API. Uyazi i-frontend enikeza le-API futhi ibonisa idatha kubasebenzisi. Uyazi i-Fetch API ukwenza izicelo ze-backend yakho, bese ukucubungula impendulo kanye nokuvakashela i-UI. I-Simple futhi enhle, eh? Okwe, ku-development, ye-yes. Emva kwalokho, uxhumane i-app yakho ekukhiqizeni. Futhi izinto eziyinkimbinkimbi zihlala. Ngokuvamile, konke kubonakala kahle, kodwa ngezinye izikhathi, imibuzo ibhizinisi. I-UI ibhizinisi. Abasebenzisi abalandeli. Umehlise ukuthi kungenzeka. I-network iyatholakala kakhulu, futhi kufuneka uxhumane. Ufuna ukufumana imibuzo eminye: Yintoni lapho inethiwekhi ivuliwe noma engatholakali? Yintoni lapho i-backend ivuliwe noma ivumela ingxubevange? Uma uxhumane i-API e-external, yini lapho uxhumane i-rate limit futhi uqhutshwa? Ungathola kanjani lezi zimo zokusebenza ngempumelelo futhi inikeze ikhono elihle lomsebenzisi? Ukwabelana, i-vanilla Fetch akuyona akufanele ukuhlangabezana nezinhlelo zayo. Ufuna ukongeza inani elikhulu le-boilerplate ikhodi ukuhlangabezana nezimo, ama-retries, ama-timeouts, ama-caching, njll. Lokhu kungase ngokushesha kubaluleke futhi kubalulekile ukugcina. Kule nqakraza, sizobuyekeza indlela yokwenza imibuzo yakho yokufaka ukukhiqizwa-ready usebenzisa i-library ebizwa Thina us: ffetch ukwakha backend nge Node.js futhi Express nge ezinye endpoints ukwakha i-frontend enikezela izindawo ezithile nge-vanilla JavaScript usebenzisa i-Fetch API ukwenza backend flaky ukuze simule izilimi zangempela Hlola kanjani imibuzo ye-catch kungabangela futhi indlela yokufakelwa kwezi imibuzo ufake ffetch ukuze ukunciphise futhi ukuphucula ukulawula isicelo fetch I-Boilerplate I-backend ithatha izindawo ze-endpoints ze-RESTful ukudala, ukucacisa, ukucacisa abasebenzisi kanye nezinsizakalo, kanye nokuthintela izinsizakalo abasebenzisi. I-frontend itholisa i-backend ukuze uthole idatha ephakeme futhi ibonisa kubasebenzisi. Ukuphakamisa Thina usebenzisa i-Node.js ne-Express ukwakha i-backend. Ngaphezu kwalokho, thina usebenzisa isitoreji se-in-memory elula ukuvikela izinto. Ngiyazi i-user kanye ne-task models: interface User { id: number; // Unique identifier name: string; // Full name email: string; // Email address } export interface Task { id: number; // Unique identifier title: string; // Short task title description?: string; // Optional detailed description priority: "low" | "medium" | "high"; // Task priority } Ukulungiselela izindawo ezilandelayo: GET /users: Thola zonke abasebenzisi (ukuguqulwa isithombe se-user ids) POST /users: Yenza umugqa omusha (ukuguqulwa id umugqa owenziwe) GET /users/:id: Get a user by id (ukuguqulwa kwe-user object) PUT /users/:id: Update a user (ukuguqulwa isitimela sokuphumula) Delete /users/:id: Ukususa umsebenzisi (ukushintshwa isitimela sokuphumula) GET /tasks: Hlola zonke izigaba (ukuguqulwa ids izigaba) GET /tasks/:id: Get a task by id (ukuguqulwa isikhwama isikhwama) POST /tasks: Yenza umsebenzi entsha (ukuguqulwa id yokwenza umsebenzi) PUT /tasks/:id: Update a task (ukuguqulwa isitimela sokuphumula) Delete /tasks/:id: Ukususa umsebenzi GET /users/:userId/tasks: Hlola zonke izivakashi ezikhishwe kubasebenzisi (ukuguqulwa ids izivakashi) POST /users/:userId/tasks/:taskId: Ukulinganisa umsebenzi kubasebenzisi (ukuguqulwa isitimela sokuphumula) DELETE /users/:userId/tasks/:taskId: Ukususa umsebenzi kusuka kumasebenzisi (ukuguqulwa isitimela sokuphumula) Ukubuyekezwa Njengoba i-frameworks ikakhulukazi ukongeza izindlela zayo zayo zayo zayo zayo zokusebenza, siza kusetshenziswe i-vanilla TypeScript ukuze ukugcina izinto ezivamile kanye ne-framework-agnostic. Siza ukwakha i-SPA nge-pages ezimbili: eyodwa ye-userlist kanye ne-user-specific. I-userlist ibonisa igama lomsebenzisi kanye ne-number of tasks eyenziwa kubo. Ukukhishwa kwe-user uzothola ku-user view, okuyinto ibonisa imininingwane yomsebenzisi kanye nezinsizakalo zayo. Futhi ukusuka ku-user view, singathola ku-userlist. Ukuze ukunikezele izinto, siza kusebenzisa ukubuyekeza ukuze uthole idatha edlule kusuka e-backend. Ngezinye izinsuku ezingu-3, siza kubhalwe e-backend ukuze uthole idatha edlule yebhizinisi elandelayo futhi usethule i-UI ngokuvumelana. Ukuze ukubonisa username, siphinde isicelo ukuze ukuze uthole zonke ids abasebenzisi, bese ngamunye abasebenzisi, siphinde isicelo ukuze ukuze ufake imibuzo yabo, futhi Ukubalwa inani lwezimali ezidlulisiwe kubo. GET /users GET /users/:id GET /users/:id/tasks Ukuze ukubukeka kubasebenzisi, sinikeza isicelo ukuze ukuze uthole imininingwane ye-user, futhi Ukuze uthole ids umsebenzi ezikhishwe kubo. Ngemuva kwalokho, ngamunye id umsebenzi, sinikeza isicelo ukuze Ukubuyekeza imizuzu yokusebenza. GET /users/:id GET /users/:id/tasks GET /tasks/:id I-GitHub ye-Repo You can find the complete code for this example in the accompanying . I-GitHub ye-repo Ngenxa yobukhulu be-boilerplate, bheka i-repo yokufaka ikhodi ephelele. Yonke isinyathelo se-artikeli kuyoba isinyathelo se-repo. I-repo ibandakanya ikhodi ye-backend kanye ne-frontend. I-backend ibandakanya ifolda, futhi frontend itholakala ku ifolda. Uma uxhumane i-repo, uxhumane izikhwama ezimbini ukufaka i-dependencies. Ngemuva kwalokho, ungakwazi ukuqhuba i-backend nge Ukusuka ifolda, futhi frontend nge Ukusuka ifolda. I-frontend iyatholakala ku Ukubuyekezwa kwe-backend . backend frontend npm install npm run dev backend npm run dev frontend http://localhost:5173 http://localhost:3000 Uma ungenza zonke izivakashi kanye kanye backend yakho kanye frontend zokusebenza, ungakwazi ukufaka browser yakho futhi uye ukuze ubone i-app esebenzayo: http://localhost:5173 Ukukhula Uma uhamba ku , kufanele ubone konke ukusebenza okungenani. Uma uchungechunge umsebenzisi omusha nge http://localhost:5173 curl -X POST http://localhost:3000/users \ -H "Content-Type: application/json" \ -d '{"name": "John Doe", "email": "john@example.com"}' you should see the user appear in the user list view within 3 imizuzu. Thola free to play around with the app and add more users and tasks. Okungenani, konke uya ukusebenza okungenani. Okwe, lokhu lapho thina lokugqibela ukufinyelela kwelanga le nqaku. I-backend yethu isebenza kahle. I-frontend yethu, ngaphandle kwe-boilerplate emangalisayo, isebenza kahle. Kodwa phakathi kwe-frontend ne-backend, kukhona inethiwekhi. Futhi inethiwekhi ayinempumelelo. Ngakho-ke, thina siphindeza ukuthi siphindezisa inethiwekhi yethu. Ukuhlobisa i-Network Errors Thina siphinde i-middleware ku-backend yethu enikezelwe ngempumelelo ngokushesha nge-20% isivinini futhi kunikeza ukuphazamiseka kwe-random kuze ku-1 inyanga. Lokhu kubonise ama-network errors futhi usiza ukuhlola ukuthi i-frontend yethu isebenzise. Ungathola i-flaky middleware ku- ifayela. Nazi ikhodi: backend/src/middleware/flaky.ts import { Request, Response, NextFunction } from 'express'; export function flaky(req: Request, res: Response, next: NextFunction) { // Randomly fail requests with a 20% chance if (Math.random() < 0.2) { return res.status(500).json({ error: 'Random failure' }); } // Add random delay up to 2 seconds const delay = Math.random() * 2000; setTimeout(next, delay); } Ngemuva kwalokho, singasebenzisa le middleware ku-App yethu ye-Express. Ungathola ikhodi ku- Okuningi ukulayisha i-middleware futhi usebenzisa ngaphambi kokufaka: backend/src/index.ts ... import { flaky } from './middleware/flaky'; ... app.use(cors()); app.use(express.json()); app.use(flaky); // Use the flaky middleware Okuzenzakalelayo Code isikhwama ye-repo, ukuze ungakwazi ukuhlola nge . network-errors git checkout network-errors Okunye, uma uhlaza backend yakho futhi uhlaza i-frontend, kufanele uqala ukubona izinto ezithakazelisayo. I-console iyatholakala ngezifiso. Ezinye izindlu ku-UI ziye Futhi lokhu lapho, uma akuyona, kufanele uqala ukuhlola kanjani ukulawula lezi zibonakali ngokushesha. undefined Ukungcweliswa Okokuqala, thina ufunde ukuthi kungenzeka ukuthi kungcono futhi indlela yokusebenza: I-intermittent network failures: Imibuzo ingangena ngempumelelo, ngakho-ke ngezinye imiphumela, kufanele ukuguqulwa ngezinye izikhathi ngaphambi kokugcina. Ngesikhathi sokubuyiselwa, sinikeza isicelo esisodwa kuphela, kodwa isicelo eziningana asynchronously. Futhi 3 imizuzu emva, sinikeza isicelo esilandelayo. Uma isicelo esilandelayo esidala lapho isigaba esilandelayo isihlahla, singatholakala isibuyekezo esilandelayo ngemuva kwesigaba esilandelayo. Lokhu kungabangela isimo se-UI esisodwa. Sinikezela ukuqinisekisa ukuthi kuphela isibuyekezo esilandelayo isetshenziselwa ukuhlaziywa kwe-UI, ngakho-ke lapho isigaba esilandelayo esisha kuqala, sinikeza isicelo esilandelayo esilandelayo esilandelayo. Ngaphezu kwalokho, uma usebenzisa ku-visit eyahlukile ngenkathi izicelo evela ku-visit edlule zihlanganisa, singathola imibuzo ye-visit edlule ngemuva kokufika. Lokhu kungabangela isimo se-UI eyahlukile. Singathola ukuthi kuphela imibuzo ye-visit elandelayo isetshenziselwa ukuhlaziywa kwe-UI, ngakho-ke lapho usebenzise ku-visit eyahlukile, kufanele ushiye izicelo ezahlukile ezahlukile ku-visit edlule. Uma isixazululo ulungele ngesikhathi esifanayo, kodwa isixazululo esizayo isixazululo esilandelayo, sincoma ngokushesha isakhiwo se-error kubasebenzisi. Sincoma isixazululo se-error ukuze abasebenzisi akuyona zonke izixazululo ezincinane ku-network. Thina ukulawula izinhlelo lapho, isibonelo, thina ukubuyekeza umugqa owenziwe e-backend. Thina ukulawula ama-error 404 ngempumelelo nokuguqulwa kwebhizinisi le-userlist, noma okungenani ukubonisa ingozi engatholakala. Ngaphezu kwalokho, kufuneka ukulawula izinhlamvu lapho i-backend iyahlukile ngokuphelele noma engatholakali. Sinikeza umbhali we-error global kubasebenzisi futhi mhlawumbe ukuguqulwa kwebhizinisi ngemva kwexesha elide. Futhi umbhalo uqhubekayo, ikakhulukazi uma UI inikeza ukwakha, ukuhlaziywa, noma ukususwa idatha. Kodwa manje, thina siphindeza imizamo yokufunda futhi indlela yokulawula imiphumela lapho ukuthatha idatha. Ukusetshenziswa kwe-Vanilla Fetch Ngiyazi, njengezinto ezininzi ze-JavaScript (noma i-TypeScript), unayo izinketho ezimbini ukulawula lezi zenzakalo. Ungayifaka izici zakho zokusebenza zokuphucula i-Fetch API futhi ukongeza isisombululo se-error handling, noma ungayifaka i-library ebonakalayo. Thola ukuqala ngokuvumelana nathi. I-code iyatholakala ku- isikhwama ye-repo, ukuze ungakwazi ukuhlola nge . native-fetch git checkout native-fetch Yini kufanele kwenziwe I-Centralize zonke i-fetch logic ku-poller.ts. Ukuze zonke izibuyekezo, ukwakha AbortController entsha, futhi ukuguqulwa edlule. I-Wrap fetch i-call ku-retry-and-timeout umsebenzi. Ngemva kokuphumelela, update cache futhi usebenzisa ukuba rendering. Ngemuva kokuphumula, re-ry njengoba kufuneka, futhi ukulawula timeouts / ukubhuka ngokushesha. Waze I-File isixazululo kusebenza lokhu: poller.ts // Cache for responses const cache: Record<string, any> = {}; // AbortController for cancelling requests let currentController: AbortController | undefined; // Helper: fetch with retries and timeout async function fetchWithRetry(url: string, options: RequestInit = {}, retries = 2, timeout = 3000): Promise<any> { for (let attempt = 0; attempt <= retries; attempt++) { const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), timeout); try { const res = await fetch(url, { ...options, signal: controller.signal }); clearTimeout(timer); if (!res.ok) throw new Error(`HTTP ${res.status}`); const data = await res.json(); return data; } catch (err) { clearTimeout(timer); if (attempt === retries) throw err; } } } // Cancel all previous requests function cancelRequests() { if (currentController) currentController.abort(); currentController = new AbortController(); } export async function fetchUserListData() { cancelRequests(); // Use cache if available if (cache.userList) return cache.userList; try { if (!currentController) throw new Error('AbortController not initialized'); const userIds = await fetchWithRetry('http://localhost:3000/users', { signal: currentController!.signal }); const users = await Promise.all(userIds.map((id: number) => fetchWithRetry(`http://localhost:3000/users/${id}`, { signal: currentController!.signal }))); const taskCounts = await Promise.all(userIds.map((id: number) => fetchWithRetry(`http://localhost:3000/users/${id}/tasks`, { signal: currentController!.signal }).then((tasks: any[]) => tasks.length))); cache.userList = { users, taskCounts }; return cache.userList; } catch (err) { // fallback to cache if available if (cache.userList) return cache.userList; throw err; } } export async function fetchUserDetailsData(userId: number) { cancelRequests(); const cacheKey = `userDetails_${userId}`; if (cache[cacheKey]) return cache[cacheKey]; try { if (!currentController) throw new Error('AbortController not initialized'); const user = await fetchWithRetry(`http://localhost:3000/users/${userId}`, { signal: currentController!.signal }); const taskIds = await fetchWithRetry(`http://localhost:3000/users/${userId}/tasks`, { signal: currentController!.signal }); const tasks = await Promise.all(taskIds.map((id: number) => fetchWithRetry(`http://localhost:3000/tasks/${id}`, { signal: currentController!.signal }))); cache[cacheKey] = { user, tasks }; return cache[cacheKey]; } catch (err) { if (cache[cacheKey]) return cache[cacheKey]; throw err; } } Ukulungiswa Njengoba yonke fetch logic iyatholakala ngoku Ngo-use case yethu eyenziwe ngempumelelo, iyatholakala, kodwa ngisho lapha, siphinde i-boilerplate ye-code yokusebenzisa ama-error, ama-retries, ama-timeouts, ama-cancellations, ne-caching. Futhi lokhu kunezinto zokufunda kuphela. Qinisekisa ukuthi ungenza i-code engaphezu kuka-create, update, kanye nokushintsha abasebenzisi, umsebenzi, futhi iziqinisekiso. api.ts poller.ts Uma usebenza i-app manje, kufanele ukuthatha ukuthi isebenza kahle kakhulu. I-UI kuyinto enhle futhi akuyona ngokushesha. Uyakwazi ukubona ezinye izibuko ku-console, kodwa zihlanganisa ngokushesha futhi akufanele ukuxhumana kwamakhasimende kakhulu. Izimpendulo ze-approximation Ngaphezu kwe-boilerplate code: Siye kubhalwe iningi le-code ukulawula ama-errors, ama-retries, ama-timeouts, ama-cancellations, ne-caching. Lokhu kungase ngokushesha kubhalwe ngempumelelo futhi kubalulekile ukugcina. I-Code iyahlukaniswa kakhulu: I-Code iyahlukaniswa ngempumelelo emzimbeni lethu ye-use and is not very reusable for other projects or scenarios. Izici ezincinane: Ikhowudi ukulawula kuphela ama-scenarios ezinzima. Ama-scenarios ezinzima ezifana ne-backoff e-exponential, ama-circuit breakers, noma ukwelashwa kwama-error e-global ngeke kuncike ikhowudi engaphezu. Ukusebenzisa Ukuze Ukusebenza Kuhle Fetch Ngena ngemvume Ngena ngemvume Ukuze ukwelashwa izinzuzo zokusebenza kokusebenzisana kwamakhasimende ethu, ngithole i-library ebizwa ngokuthi Kuyinto ibhizinisi elincane futhi elula elihlanganisa i-Fetch API futhi inikeza indlela efanelekayo futhi enikezayo yokulawula ama-errors, ama-retries, ama-timeouts, ama-cancellations, futhi ezinye izici ezingaphezu. ffetch Let's rewrite yethu fetch logic usebenzisa . Ungathola ikhodi ku- isikhwama ye-repo, ukuze ungakwazi ukuhlola nge . ffetch ffetch git checkout ffetch Okokuqala, ukufaka Ukusuka Ibhokisi: ffetch frontend npm install @gkoos/ffetch Ngemuva kwalokho, singakwazi ukulayisha ifayela usebenzisa : poller.ts ffetch import createClient from '@gkoos/ffetch'; // Cache for responses const cache: Record<string, any> = {}; // Create ffetch client const api = createClient({ timeout: 3000, retries: 2, }); function cancelRequests() { api.abortAll(); } export async function fetchUserListData() { cancelRequests(); if (cache.userList) return cache.userList; try { const userIds = await api('http://localhost:3000/users').then(r => r.json()); const users = await Promise.all( userIds.map((id: number) => api(`http://localhost:3000/users/${id}`).then(r => r.json())) ); const taskCounts = await Promise.all( userIds.map((id: number) => api(`http://localhost:3000/users/${id}/tasks`).then(r => r.json()).then((tasks: any[]) => tasks.length)) ); cache.userList = { users, taskCounts }; return cache.userList; } catch (err) { if (cache.userList) return cache.userList; throw err; } } export async function fetchUserDetailsData(userId: number) { cancelRequests(); const cacheKey = `userDetails_${userId}`; if (cache[cacheKey]) return cache[cacheKey]; try { const user = await api(`http://localhost:3000/users/${userId}`).then(r => r.json()); const taskIds = await api(`http://localhost:3000/users/${userId}/tasks`).then(r => r.json()); const tasks = await Promise.all( taskIds.map((id: number) => api(`http://localhost:3000/tasks/${id}`).then(r => r.json())) ); cache[cacheKey] = { user, tasks }; return cache[cacheKey]; } catch (err) { if (cache[cacheKey]) return cache[cacheKey]; throw err; } } Ikhodi kuyinto enhle kakhulu futhi kulula ukufunda. Thina akufanele ukhangele ama-retries, ama-timeouts, noma ama-cancelations. Thina nje ukwakha i-client nge-options esithakazelisayo futhi usebenzisa lokhu ukwenza imibuzo. ffetch Izinzuzo Zezinye Zokusebenzisa ffetch I-Circuit Breaker: Ukushisa okuzenzakalelayo kwe-endpoint ngemuva kwamakhemikhali amaningi I-automatic exponential backoff ye-retries: ukwandisa isikhathi sokuhamba phakathi kwe-retries Ukusebenza kwe-Global Error: i-hooks yokubhalisa, ukuguqulwa kwezicelo / imibuzo, njll Ngokusho, singakwazi ukuguqulwa okungenani izixazululo ezivela ku-retry, futhi ukuthi kungekho. Ngokwesibonelo, singakwazi ukuguqulwa ku-network errors kanye ne-5xx server errors, kodwa kungekho ku-4xx client errors. Ngaba ungenza into emangalisayo ungayifakile, kodwa ungacindezela ukuchofoza, ukuhlolwa, nokuthuthukiswa yonke le boilerplate. Kuyinto i-comfort wrapper enikezela izakhiwo zokukhiqiza (njenge-circuit breaker kanye ne-backoff) ukuze ungathola isicelo sakho, futhi akuyona logic yakho yokufaka. It futhi kusekwe ku-catch layer, ngakho-ke ungasebenzisa isikhwama lakho lokufaka, ukulawula kwegama, kanye ne-UI amabhizinisi lapho ungacindezela. ffetch Ukuphakama Umthombo wokuqala wesixhumanisi wesixhumanisi wesixhumanisi wesixhumanisi wesixhumanisi Ngokuphathelene, kodwa ukuthi kufanele akufanele i-vanilla Fetch izicelo zokukhiqiza. Inethiwekhi akufanele, futhi kufuneka uxhumane kulokhu. Ufuna ukulawula ama-errors, ama-retries, ama-timeouts, ama-cancellations, kanye ne-cache ngokushesha ukuze inikeze isicelo esihle. ffetch Yini nje kufuneka ukwenza kulingana nezidingo zakho ezithile zokusebenzisa, kodwa ungase ukufinyelela ekukhiqizeni ukulawula kuphela isitimela enhle. Izinto zingatholakala futhi zokusebenza kahle, futhi isicelo yakho kufanele ukulawula okungenani izibonelo ezivamile zokungasebenzi. Futhi Ngaba ungasiza lokhu. ffetch