વૈશ્વિક એપ્લિકેશન્સમાં કાર્યક્ષમ અને મજબૂત એસિંક્રોનસ પ્રોગ્રામિંગ માટે જાવાસ્ક્રિપ્ટ પ્રોમિસ કોમ્બિનેટર્સ (Promise.all, Promise.allSettled, Promise.race, Promise.any) માં નિપુણતા મેળવો.
જાવાસ્ક્રિપ્ટ પ્રોમિસ કોમ્બિનેટર્સ: વૈશ્વિક એપ્લિકેશન્સ માટે એડવાન્સ્ડ એસિંક પેટર્ન્સ
એસિંક્રોનસ પ્રોગ્રામિંગ આધુનિક જાવાસ્ક્રિપ્ટનો પાયાનો પથ્થર છે, ખાસ કરીને જ્યારે વેબ એપ્લિકેશન્સ બનાવતી વખતે જે APIs, ડેટાબેસેસ સાથે ક્રિયાપ્રતિક્રિયા કરે છે, અથવા સમય માંગી લેતી કામગીરી કરે છે. જાવાસ્ક્રિપ્ટ પ્રોમિસીસ એસિંક્રોનસ કામગીરીનું સંચાલન કરવા માટે એક શક્તિશાળી એબ્સ્ટ્રેક્શન પ્રદાન કરે છે, પરંતુ તેમાં નિપુણતા મેળવવા માટે એડવાન્સ્ડ પેટર્ન્સને સમજવાની જરૂર છે. આ લેખ જાવાસ્ક્રિપ્ટ પ્રોમિસ કોમ્બિનેટર્સ – Promise.all, Promise.allSettled, Promise.race, અને Promise.any – માં ઊંડાણપૂર્વક અભ્યાસ કરે છે અને કેવી રીતે તેનો ઉપયોગ કાર્યક્ષમ અને મજબૂત એસિંક્રોનસ વર્કફ્લો બનાવવા માટે કરી શકાય છે, ખાસ કરીને વૈશ્વિક એપ્લિકેશન્સના સંદર્ભમાં જ્યાં નેટવર્કની સ્થિતિ અને ડેટા સ્રોતો અલગ અલગ હોય છે.
પ્રોમિસીસને સમજવું: એક ઝડપી રિકેપ
કોમ્બિનેટર્સમાં ડૂબકી મારતા પહેલાં, ચાલો પ્રોમિસીસની ઝડપથી સમીક્ષા કરીએ. એક પ્રોમિસ એસિંક્રોનસ કામગીરીના અંતિમ પરિણામનું પ્રતિનિધિત્વ કરે છે. તે ત્રણમાંથી કોઈ એક સ્થિતિમાં હોઈ શકે છે:
- પેન્ડિંગ: પ્રારંભિક સ્થિતિ, ન તો પૂર્ણ કે ન તો નકારાયેલ.
- ફુલફિલ્ડ: કામગીરી સફળતાપૂર્વક પૂર્ણ થઈ, પરિણામી મૂલ્ય સાથે.
- રિજેક્ટેડ: કામગીરી નિષ્ફળ ગઈ, કારણ સાથે (સામાન્ય રીતે એક એરર ઓબ્જેક્ટ).
પ્રોમિસીસ પરંપરાગત કોલબેક્સની તુલનામાં એસિંક્રોનસ કામગીરીને હેન્ડલ કરવાની વધુ સ્વચ્છ અને વ્યવસ્થિત રીત પ્રદાન કરે છે. તે કોડની વાંચનક્ષમતા સુધારે છે અને એરર હેન્ડલિંગને સરળ બનાવે છે. નિર્ણાયક રીતે, તે પ્રોમિસ કોમ્બિનેટર્સ માટેનો આધાર પણ બનાવે છે જેનો આપણે અભ્યાસ કરીશું.
પ્રોમિસ કોમ્બિનેટર્સ: એસિંક્રોનસ ઓપરેશન્સનું સંચાલન
પ્રોમિસ કોમ્બિનેટર્સ એ Promise ઓબ્જેક્ટ પરની સ્ટેટિક મેથડ્સ છે જે તમને બહુવિધ પ્રોમિસીસનું સંચાલન અને સંકલન કરવાની મંજૂરી આપે છે. તે જટિલ એસિંક્રોનસ વર્કફ્લો બનાવવા માટે શક્તિશાળી સાધનો પૂરા પાડે છે. ચાલો દરેકની વિગતવાર તપાસ કરીએ.
Promise.all(): પ્રોમિસીસને સમાંતર રીતે એક્ઝિક્યુટ કરવું અને પરિણામોને એકત્રિત કરવા
Promise.all() ઇનપુટ તરીકે પ્રોમિસીસનો એક ઇટરેબલ (સામાન્ય રીતે એક એરે) લે છે અને એક જ પ્રોમિસ પરત કરે છે. આ પરત થયેલ પ્રોમિસ ત્યારે પૂર્ણ થાય છે જ્યારે બધા ઇનપુટ પ્રોમિસીસ પૂર્ણ થઈ જાય છે. જો કોઈ પણ ઇનપુટ પ્રોમિસ રિજેક્ટ થાય છે, તો પરત થયેલ પ્રોમિસ તરત જ પ્રથમ રિજેક્ટ થયેલ પ્રોમિસના કારણ સાથે રિજેક્ટ થાય છે.
ઉપયોગનો કિસ્સો: જ્યારે તમારે એક સાથે બહુવિધ APIs માંથી ડેટા મેળવવાની અને સંયુક્ત પરિણામો પર પ્રક્રિયા કરવાની જરૂર હોય, ત્યારે Promise.all() આદર્શ છે. ઉદાહરણ તરીકે, એક ડેશબોર્ડ બનાવવાની કલ્પના કરો જે વિશ્વના વિવિધ શહેરોની હવામાન માહિતી દર્શાવે છે. દરેક શહેરનો ડેટા એક અલગ API કોલ દ્વારા મેળવી શકાય છે.
async function fetchWeatherData(city) {
try {
const response = await fetch(`https://api.example.com/weather?city=${city}`); // Replace with a real API endpoint
if (!response.ok) {
throw new Error(`Failed to fetch weather data for ${city}`);
}
return await response.json();
} catch (error) {
console.error(`Error fetching weather data for ${city}: ${error}`);
throw error; // Re-throw the error to be caught by Promise.all
}
}
async function displayWeatherData() {
const cities = ['London', 'Tokyo', 'New York', 'Sydney'];
try {
const weatherDataPromises = cities.map(city => fetchWeatherData(city));
const weatherData = await Promise.all(weatherDataPromises);
weatherData.forEach((data, index) => {
console.log(`Weather in ${cities[index]}:`, data);
// Update the UI with the weather data
});
} catch (error) {
console.error('Failed to fetch weather data for all cities:', error);
// Display an error message to the user
}
}
displayWeatherData();
વૈશ્વિક એપ્લિકેશન્સ માટે વિચારણાઓ:
- નેટવર્ક લેટન્સી: વિવિધ ભૌગોલિક સ્થળોએ વિવિધ APIs માટેની વિનંતીઓ અલગ-અલગ લેટન્સીનો અનુભવ કરી શકે છે.
Promise.all()એ ક્રમની ગેરંટી આપતું નથી કે જેમાં પ્રોમિસીસ પૂર્ણ થશે, ફક્ત એટલું જ કે તે બધા પૂર્ણ થશે (અથવા એક રિજેક્ટ થશે) તે પહેલાં સંયુક્ત પ્રોમિસ સેટલ થાય. - API રેટ લિમિટિંગ: જો તમે સમાન API અથવા શેર કરેલ રેટ લિમિટવાળા બહુવિધ APIs પર બહુવિધ વિનંતીઓ કરી રહ્યાં છો, તો તમે તે મર્યાદાઓ ઓળંગી શકો છો. રેટ લિમિટિંગને યોગ્ય રીતે હેન્ડલ કરવા માટે વિનંતીઓને કતારમાં મૂકવા અથવા એક્સપોનેન્શિયલ બેકઓફનો ઉપયોગ કરવા જેવી વ્યૂહરચનાઓ લાગુ કરો.
- એરર હેન્ડલિંગ: યાદ રાખો કે જો કોઈપણ પ્રોમિસ રિજેક્ટ થાય, તો સમગ્ર
Promise.all()ઓપરેશન નિષ્ફળ જાય છે. જો તમે અમુક વિનંતીઓ નિષ્ફળ જાય તો પણ આંશિક ડેટા પ્રદર્શિત કરવા માંગતા હોવ તો આ ઇચ્છનીય ન હોઈ શકે. આવા કિસ્સાઓમાંPromise.allSettled()નો ઉપયોગ કરવાનું વિચારો (નીચે સમજાવેલ છે).
Promise.allSettled(): સફળતા અને નિષ્ફળતાને વ્યક્તિગત રીતે હેન્ડલ કરવું
Promise.allSettled() એ Promise.all() જેવું જ છે, પરંતુ એક મહત્ત્વના તફાવત સાથે: તે બધા ઇનપુટ પ્રોમિસીસ સેટલ થાય તેની રાહ જુએ છે, ભલે તે પૂર્ણ થાય કે રિજેક્ટ. પરત થયેલ પ્રોમિસ હંમેશા ઓબ્જેક્ટ્સની એરે સાથે પૂર્ણ થાય છે, જેમાં દરેક ઓબ્જેક્ટ સંબંધિત ઇનપુટ પ્રોમિસના પરિણામનું વર્ણન કરે છે. દરેક ઓબ્જેક્ટમાં status પ્રોપર્ટી (ક્યાં તો "fulfilled" અથવા "rejected") અને value (જો પૂર્ણ થયું હોય) અથવા reason (જો રિજેક્ટ થયું હોય) પ્રોપર્ટી હોય છે.
ઉપયોગનો કિસ્સો: જ્યારે તમારે બહુવિધ એસિંક્રોનસ ઓપરેશન્સના પરિણામો ભેગા કરવાની જરૂર હોય, અને તેમાંથી કેટલાક નિષ્ફળ જાય તો સમગ્ર ઓપરેશન નિષ્ફળ ન જાય તે સ્વીકાર્ય હોય, ત્યારે Promise.allSettled() વધુ સારો વિકલ્પ છે. એવી સિસ્ટમની કલ્પના કરો જે બહુવિધ પેમેન્ટ ગેટવે દ્વારા પેમેન્ટ્સ પર પ્રક્રિયા કરે છે. તમે બધા પેમેન્ટ્સનો પ્રયાસ કરવા અને કયા સફળ થયા અને કયા નિષ્ફળ થયા તેની નોંધ રાખવા માગી શકો છો.
async function processPayment(paymentGateway, amount) {
try {
const response = await paymentGateway.process(amount); // Replace with a real payment gateway integration
if (response.status === 'success') {
return { status: 'fulfilled', value: `Payment processed successfully via ${paymentGateway.name}` };
} else {
throw new Error(`Payment failed via ${paymentGateway.name}: ${response.message}`);
}
} catch (error) {
return { status: 'rejected', reason: `Payment failed via ${paymentGateway.name}: ${error.message}` };
}
}
async function processMultiplePayments(paymentGateways, amount) {
const paymentPromises = paymentGateways.map(gateway => processPayment(gateway, amount));
const results = await Promise.allSettled(paymentPromises);
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(result.value);
} else {
console.error(result.reason);
}
});
// Analyze the results to determine overall success/failure
const successfulPayments = results.filter(result => result.status === 'fulfilled').length;
const failedPayments = results.filter(result => result.status === 'rejected').length;
console.log(`Successful payments: ${successfulPayments}`);
console.log(`Failed payments: ${failedPayments}`);
}
// Example payment gateways
const paymentGateways = [
{ name: 'PayPal', process: (amount) => Promise.resolve({ status: 'success', message: 'Payment successful' }) },
{ name: 'Stripe', process: (amount) => Promise.reject({ status: 'error', message: 'Insufficient funds' }) },
{ name: 'Worldpay', process: (amount) => Promise.resolve({ status: 'success', message: 'Payment successful' }) },
];
processMultiplePayments(paymentGateways, 100);
વૈશ્વિક એપ્લિકેશન્સ માટે વિચારણાઓ:
- મજબૂતાઈ:
Promise.allSettled()તમારી એપ્લિકેશન્સની મજબૂતાઈને વધારે છે કારણ કે તે ખાતરી કરે છે કે બધી એસિંક્રોનસ કામગીરીનો પ્રયાસ કરવામાં આવે છે, ભલે તેમાંની કેટલીક નિષ્ફળ જાય. આ ખાસ કરીને વિતરિત સિસ્ટમ્સમાં મહત્વપૂર્ણ છે જ્યાં નિષ્ફળતાઓ સામાન્ય છે. - વિગતવાર રિપોર્ટિંગ: પરિણામોની એરે દરેક ઓપરેશનના પરિણામ વિશે વિગતવાર માહિતી પૂરી પાડે છે, જે તમને એરર લોગ કરવા, નિષ્ફળ ઓપરેશન્સનો ફરીથી પ્રયાસ કરવા અથવા વપરાશકર્તાઓને વિશિષ્ટ પ્રતિસાદ આપવા દે છે.
- આંશિક સફળતા: તમે સરળતાથી એકંદર સફળતા દર નક્કી કરી શકો છો અને સફળ અને નિષ્ફળ ઓપરેશન્સની સંખ્યાના આધારે યોગ્ય પગલાં લઈ શકો છો. ઉદાહરણ તરીકે, જો પ્રાથમિક ગેટવે નિષ્ફળ જાય તો તમે વૈકલ્પિક પેમેન્ટ પદ્ધતિઓ ઓફર કરી શકો છો.
Promise.race(): સૌથી ઝડપી પરિણામ પસંદ કરવું
Promise.race() પણ ઇનપુટ તરીકે પ્રોમિસીસનો એક ઇટરેબલ લે છે અને એક જ પ્રોમિસ પરત કરે છે. જોકે, Promise.all() અને Promise.allSettled() થી વિપરીત, Promise.race() ઇનપુટ પ્રોમિસીસમાંથી કોઈપણ એક સેટલ થતાંની સાથે જ સેટલ થઈ જાય છે (ક્યાં તો પૂર્ણ થાય કે રિજેક્ટ). પરત થયેલ પ્રોમિસ પ્રથમ સેટલ થયેલ પ્રોમિસના મૂલ્ય અથવા કારણ સાથે પૂર્ણ અથવા રિજેક્ટ થાય છે.
ઉપયોગનો કિસ્સો: જ્યારે તમારે બહુવિધ સ્રોતોમાંથી સૌથી ઝડપી પ્રતિસાદ પસંદ કરવાની જરૂર હોય, ત્યારે Promise.race() એક સારો વિકલ્પ છે. કલ્પના કરો કે તમે સમાન ડેટા માટે બહુવિધ સર્વરોને ક્વેરી કરી રહ્યાં છો અને તમને મળેલ પ્રથમ પ્રતિસાદનો ઉપયોગ કરી રહ્યાં છો. આ પ્રદર્શન અને પ્રતિભાવમાં સુધારો કરી શકે છે, ખાસ કરીને એવી પરિસ્થિતિઓમાં જ્યાં કેટલાક સર્વર અસ્થાયી રૂપે અનુપલબ્ધ અથવા અન્ય કરતા ધીમા હોઈ શકે છે.
async function fetchDataFromServer(serverURL) {
try {
const response = await fetch(serverURL, {signal: AbortSignal.timeout(5000)}); //Add a timeout of 5 seconds
if (!response.ok) {
throw new Error(`Failed to fetch data from ${serverURL}`);
}
return await response.json();
} catch (error) {
console.error(`Error fetching data from ${serverURL}: ${error}`);
throw error;
}
}
async function getFastestResponse() {
const serverURLs = [
'https://server1.example.com/data', // Replace with real server URLs
'https://server2.example.com/data',
'https://server3.example.com/data',
];
try {
const dataPromises = serverURLs.map(serverURL => fetchDataFromServer(serverURL));
const fastestData = await Promise.race(dataPromises);
console.log('Fastest data received:', fastestData);
// Use the fastest data
} catch (error) {
console.error('Failed to get data from any server:', error);
// Handle the error
}
}
getFastestResponse();
વૈશ્વિક એપ્લિકેશન્સ માટે વિચારણાઓ:
- ટાઇમઆઉટ્સ:
Promise.race()નો ઉપયોગ કરતી વખતે ટાઇમઆઉટ્સ લાગુ કરવું નિર્ણાયક છે જેથી પરત થયેલ પ્રોમિસ અનિશ્ચિત સમય સુધી રાહ ન જુએ જો કેટલાક ઇનપુટ પ્રોમિસીસ ક્યારેય સેટલ ન થાય. ઉપરોક્ત ઉદાહરણ આ હાંસલ કરવા માટે `AbortSignal.timeout()` નો ઉપયોગ કરે છે. - નેટવર્કની સ્થિતિ: સૌથી ઝડપી સર્વર વપરાશકર્તાના ભૌગોલિક સ્થાન અને નેટવર્કની સ્થિતિને આધારે બદલાઈ શકે છે. તમારી સામગ્રીને વિતરિત કરવા અને વિશ્વભરના વપરાશકર્તાઓ માટે પ્રદર્શન સુધારવા માટે કન્ટેન્ટ ડિલિવરી નેટવર્ક (CDN) નો ઉપયોગ કરવાનું વિચારો.
- એરર હેન્ડલિંગ: જો રેસ 'જીતનાર' પ્રોમિસ રિજેક્ટ થાય છે, તો સમગ્ર Promise.race રિજેક્ટ થાય છે. ખાતરી કરો કે દરેક પ્રોમિસમાં અનપેક્ષિત રિજેક્શનને રોકવા માટે યોગ્ય એરર હેન્ડલિંગ છે. ઉપરાંત, જો "વિજેતા" પ્રોમિસ ટાઇમઆઉટને કારણે રિજેક્ટ થાય છે (ઉપર બતાવ્યા પ્રમાણે), તો અન્ય પ્રોમિસીસ બેકગ્રાઉન્ડમાં ચાલુ રહેશે. જો તે અન્ય પ્રોમિસીસની હવે જરૂર ન હોય તો તેને રદ કરવા માટે તમારે `AbortController` નો ઉપયોગ કરીને લોજિક ઉમેરવાની જરૂર પડી શકે છે.
Promise.any(): પ્રથમ પૂર્ણતા સ્વીકારવી
Promise.any() એ Promise.race() જેવું જ છે, પરંતુ થોડા અલગ વર્તન સાથે. તે પ્રથમ ઇનપુટ પ્રોમિસ પૂર્ણ થાય તેની રાહ જુએ છે. જો બધા ઇનપુટ પ્રોમિસીસ રિજેક્ટ થાય, તો Promise.any() એક AggregateError સાથે રિજેક્ટ થાય છે જેમાં રિજેક્શનના કારણોની એરે હોય છે.
ઉપયોગનો કિસ્સો: જ્યારે તમારે બહુવિધ સ્રોતોમાંથી ડેટા પુનઃપ્રાપ્ત કરવાની જરૂર હોય, અને તમે ફક્ત પ્રથમ સફળ પરિણામની જ ચિંતા કરતા હો, ત્યારે Promise.any() એક સારો વિકલ્પ છે. આ ત્યારે ઉપયોગી છે જ્યારે તમારી પાસે રિડન્ડન્ટ ડેટા સ્રોતો અથવા વૈકલ્પિક APIs હોય જે સમાન માહિતી પ્રદાન કરે છે. તે ગતિ કરતાં સફળતાને પ્રાથમિકતા આપે છે, કારણ કે તે પ્રથમ પૂર્ણતાની રાહ જુએ છે, ભલે કેટલાક પ્રોમિસીસ ઝડપથી રિજેક્ટ થાય.
async function fetchDataFromSource(sourceURL) {
try {
const response = await fetch(sourceURL);
if (!response.ok) {
throw new Error(`Failed to fetch data from ${sourceURL}`);
}
return await response.json();
} catch (error) {
console.error(`Error fetching data from ${sourceURL}: ${error}`);
throw error;
}
}
async function getFirstSuccessfulData() {
const dataSources = [
'https://source1.example.com/data', // Replace with real data source URLs
'https://source2.example.com/data',
'https://source3.example.com/data',
];
try {
const dataPromises = dataSources.map(sourceURL => fetchDataFromSource(sourceURL));
const data = await Promise.any(dataPromises);
console.log('First successful data received:', data);
// Use the successful data
} catch (error) {
if (error instanceof AggregateError) {
console.error('Failed to get data from any source:', error.errors);
// Handle the error
} else {
console.error('An unexpected error occurred:', error);
}
}
}
getFirstSuccessfulData();
વૈશ્વિક એપ્લિકેશન્સ માટે વિચારણાઓ:
- રિડન્ડન્સી:
Promise.any()ખાસ કરીને ત્યારે ઉપયોગી છે જ્યારે રિડન્ડન્ટ ડેટા સ્રોતો સાથે કામ કરતી વખતે જે સમાન માહિતી પ્રદાન કરે છે. જો એક સ્રોત અનુપલબ્ધ અથવા ધીમો હોય, તો તમે ડેટા પ્રદાન કરવા માટે અન્ય પર આધાર રાખી શકો છો. - એરર હેન્ડલિંગ: જ્યારે બધા ઇનપુટ પ્રોમિસીસ રિજેક્ટ થાય ત્યારે ફેંકવામાં આવતી
AggregateErrorને હેન્ડલ કરવાની ખાતરી કરો. આ એરરમાં વ્યક્તિગત રિજેક્શન કારણોની એક એરે હોય છે, જે તમને સમસ્યાઓનું ડિબગીંગ અને નિદાન કરવાની મંજૂરી આપે છે. - પ્રાથમિકતા: તમે
Promise.any()ને જે ક્રમમાં પ્રોમિસીસ પ્રદાન કરો છો તે મહત્વનું છે. સફળ પરિણામની સંભાવના વધારવા માટે સૌથી વિશ્વસનીય અથવા સૌથી ઝડપી ડેટા સ્રોતોને પહેલા મૂકો.
યોગ્ય કોમ્બિનેટર પસંદ કરવું: એક સારાંશ
તમારી જરૂરિયાતો માટે યોગ્ય પ્રોમિસ કોમ્બિનેટર પસંદ કરવામાં તમારી મદદ કરવા માટે અહીં એક ઝડપી સારાંશ છે:
- Promise.all(): જ્યારે તમારે બધા પ્રોમિસીસ સફળતાપૂર્વક પૂર્ણ થાય તેની જરૂર હોય ત્યારે ઉપયોગ કરો, અને જો કોઈ પ્રોમિસ રિજેક્ટ થાય તો તમે તરત જ નિષ્ફળ થવા માંગતા હો.
- Promise.allSettled(): જ્યારે તમે બધા પ્રોમિસીસ સેટલ થાય તેની રાહ જોવા માંગતા હો, સફળતા કે નિષ્ફળતાને ધ્યાનમાં લીધા વિના, અને તમારે દરેક પરિણામ વિશે વિગતવાર માહિતીની જરૂર હોય ત્યારે ઉપયોગ કરો.
- Promise.race(): જ્યારે તમે બહુવિધ પ્રોમિસીસમાંથી સૌથી ઝડપી પરિણામ પસંદ કરવા માંગતા હો, અને તમે ફક્ત પ્રથમ સેટલ થનારની જ ચિંતા કરતા હો ત્યારે ઉપયોગ કરો.
- Promise.any(): જ્યારે તમે બહુવિધ પ્રોમિસીસમાંથી પ્રથમ સફળ પરિણામ સ્વીકારવા માંગતા હો, અને જો કેટલાક પ્રોમિસીસ રિજેક્ટ થાય તો તમને વાંધો ન હોય ત્યારે ઉપયોગ કરો.
એડવાન્સ્ડ પેટર્ન્સ અને શ્રેષ્ઠ પદ્ધતિઓ
પ્રોમિસ કોમ્બિનેટર્સના મૂળભૂત ઉપયોગ ઉપરાંત, ધ્યાનમાં રાખવા માટે ઘણી એડવાન્સ્ડ પેટર્ન્સ અને શ્રેષ્ઠ પદ્ધતિઓ છે:
કન્કરન્સી મર્યાદિત કરવી
જ્યારે મોટી સંખ્યામાં પ્રોમિસીસ સાથે કામ કરતી વખતે, તે બધાને સમાંતર રીતે એક્ઝિક્યુટ કરવાથી તમારી સિસ્ટમ ઓવરલોડ થઈ શકે છે અથવા API રેટ લિમિટ્સ ઓળંગી શકે છે. તમે આ જેવી તકનીકોનો ઉપયોગ કરીને કન્કરન્સી મર્યાદિત કરી શકો છો:
- ચંકિંગ (ટુકડા કરવા): પ્રોમિસીસને નાના ટુકડાઓમાં વિભાજીત કરો અને દરેક ટુકડાને ક્રમિક રીતે પ્રોસેસ કરો.
- સેમાફોરનો ઉપયોગ: સમવર્તી કામગીરીની સંખ્યાને નિયંત્રિત કરવા માટે સેમાફોર લાગુ કરો.
અહીં ચંકિંગનો ઉપયોગ કરીને એક ઉદાહરણ છે:
async function processInChunks(promises, chunkSize) {
const results = [];
for (let i = 0; i < promises.length; i += chunkSize) {
const chunk = promises.slice(i, i + chunkSize);
const chunkResults = await Promise.all(chunk);
results.push(...chunkResults);
}
return results;
}
// Example usage
const myPromises = [...Array(100)].map((_, i) => Promise.resolve(i)); //Create 100 promises
processInChunks(myPromises, 10) // Process 10 promises at a time
.then(results => console.log('All promises resolved:', results));
એરર્સને યોગ્ય રીતે હેન્ડલ કરવી
પ્રોમિસીસ સાથે કામ કરતી વખતે યોગ્ય એરર હેન્ડલિંગ નિર્ણાયક છે. એસિંક્રોનસ ઓપરેશન્સ દરમિયાન થઈ શકે તેવી એરર્સને પકડવા માટે try...catch બ્લોક્સનો ઉપયોગ કરો. નિષ્ફળ ઓપરેશન્સને આપમેળે ફરીથી પ્રયાસ કરવા માટે p-retry અથવા retry જેવી લાઇબ્રેરીઓનો ઉપયોગ કરવાનું વિચારો.
async function fetchDataWithRetry(url, retries = 3) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
if (retries > 0) {
console.log(`Retrying in 1 second... (Retries left: ${retries})`);
await new Promise(resolve => setTimeout(resolve, 1000)); // Wait 1 second
return fetchDataWithRetry(url, retries - 1);
} else {
console.error('Max retries reached. Operation failed.');
throw error;
}
}
}
Async/Await નો ઉપયોગ કરવો
async અને await પ્રોમિસીસ સાથે કામ કરવાની વધુ સિંક્રોનસ જેવી દેખાતી રીત પ્રદાન કરે છે. તે કોડની વાંચનક્ષમતા અને જાળવણીક્ષમતામાં નોંધપાત્ર સુધારો કરી શકે છે.
સંભવિત એરર્સને હેન્ડલ કરવા માટે await એક્સપ્રેશન્સની આસપાસ try...catch બ્લોક્સનો ઉપયોગ કરવાનું યાદ રાખો.
રદ કરવું (Cancellation)
કેટલાક કિસ્સાઓમાં, તમારે પેન્ડિંગ પ્રોમિસીસને રદ કરવાની જરૂર પડી શકે છે, ખાસ કરીને જ્યારે લાંબા સમય સુધી ચાલતી કામગીરી અથવા વપરાશકર્તા દ્વારા શરૂ કરાયેલી ક્રિયાઓ સાથે કામ કરતી વખતે. તમે AbortController API નો ઉપયોગ કરીને સંકેત આપી શકો છો કે પ્રોમિસ રદ થવો જોઈએ.
const controller = new AbortController();
const signal = controller.signal;
async function fetchDataWithCancellation(url) {
try {
const response = await fetch(url, { signal });
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
if (error.name === 'AbortError') {
console.log('Fetch aborted');
} else {
console.error('Error fetching data:', error);
}
throw error;
}
}
fetchDataWithCancellation('https://api.example.com/data')
.then(data => console.log('Data received:', data))
.catch(error => console.error('Fetch failed:', error));
// Cancel the fetch operation after 5 seconds
setTimeout(() => {
controller.abort();
}, 5000);
નિષ્કર્ષ
જાવાસ્ક્રિપ્ટ પ્રોમિસ કોમ્બિનેટર્સ મજબૂત અને કાર્યક્ષમ એસિંક્રોનસ એપ્લિકેશન્સ બનાવવા માટે શક્તિશાળી સાધનો છે. Promise.all, Promise.allSettled, Promise.race, અને Promise.any ની સૂક્ષ્મતાને સમજીને, તમે જટિલ એસિંક્રોનસ વર્કફ્લો ગોઠવી શકો છો, એરર્સને યોગ્ય રીતે હેન્ડલ કરી શકો છો, અને પ્રદર્શનને શ્રેષ્ઠ બનાવી શકો છો. વૈશ્વિક એપ્લિકેશન્સ વિકસાવતી વખતે, નેટવર્ક લેટન્સી, API રેટ લિમિટ્સ, અને ડેટા સ્રોતની વિશ્વસનીયતાને ધ્યાનમાં લેવી નિર્ણાયક છે. આ લેખમાં ચર્ચા કરાયેલ પેટર્ન્સ અને શ્રેષ્ઠ પદ્ધતિઓ લાગુ કરીને, તમે જાવાસ્ક્રિપ્ટ એપ્લિકેશન્સ બનાવી શકો છો જે પ્રદર્શનશીલ અને સ્થિતિસ્થાપક બંને હોય, જે વિશ્વભરના વપરાશકર્તાઓને શ્રેષ્ઠ વપરાશકર્તા અનુભવ પ્રદાન કરે છે.