JavaScriptéåæã€ãã¬ãŒã¿ãã«ããŒé£æºãšã³ãžã³ããã¹ã¿ãŒããå¹ççãªéåæã¹ããªãŒã 管çãå®çŸãã³ã¢ã³ã³ã»ãããå®è·µäŸãå®äžçã®å¿çšã解説ããŸãã
JavaScriptéåæã€ãã¬ãŒã¿ãã«ããŒé£æºãšã³ãžã³ïŒéåæã¹ããªãŒã 管ç
éåæããã°ã©ãã³ã°ã¯ãç¹ã«ããŒã¿ã®ã¹ããªãŒã ããªã¢ã«ã¿ã€ã æŽæ°ãAPIãšã®å¯Ÿè©±ãæ±ãç°å¢ã«ãããŠãçŸä»£ã®JavaScriptã®åºæ¬ã§ããJavaScriptéåæã€ãã¬ãŒã¿ãã«ããŒé£æºãšã³ãžã³ã¯ããããã®éåæã¹ããªãŒã ã广çã«ç®¡çããããã®åŒ·åãªãã¬ãŒã ã¯ãŒã¯ãæäŸããŸãããã®å æ¬çãªã¬ã€ãã§ã¯ãéåæã€ãã¬ãŒã¿ãéåæãžã§ãã¬ãŒã¿ãããã³ãããã®é£æºã«é¢ããã³ã¢ã³ã³ã»ãããå®è·µçãªå¿çšãé«åºŠãªãã¯ããã¯ãæ¢æ±ããå ç¢ã§å¹ççãªéåæãœãªã¥ãŒã·ã§ã³ãæ§ç¯ããåãäžããŸãã
éåæã€ãã¬ãŒã·ã§ã³ã®åºç€ãçè§£ãã
飿ºã®è€éãã«é£ã³èŸŒãåã«ãéåæã€ãã¬ãŒã¿ãšéåæãžã§ãã¬ãŒã¿ã®ç¢ºåºããçè§£ã確ç«ããŸããããECMAScript 2018ã§å°å ¥ããããããã®æ©èœã¯ãéåæããŒã¿ã·ãŒã±ã³ã¹ãæ±ãããã«äžå¯æ¬ ã§ãã
éåæã€ãã¬ãŒã¿
éåæã€ãã¬ãŒã¿ãšã¯ãPromiseãè¿ã`next()`ã¡ãœãããæã€ãªããžã§ã¯ãã§ãããã®Promiseã¯ã`value`ïŒæ¬¡ã«yieldãããå€ïŒãš`done`ïŒã€ãã¬ãŒã·ã§ã³ãå®äºãããã瀺ãããŒã«å€ïŒãšãã2ã€ã®ããããã£ãæã€ãªããžã§ã¯ãã«è§£æ±ºãããŸããããã«ããããããã¯ãŒã¯ãªã¯ãšã¹ãããã¡ã€ã«ã¹ããªãŒã ãããŒã¿ããŒã¹ã¯ãšãªãªã©ã®éåæããŒã¿ãœãŒã¹ãå埩åŠçã§ããŸãã
è€æ°ã®APIããåæã«ããŒã¿ãååŸããå¿ èŠãããã·ããªãªãèããŠã¿ãŸããããåAPIåŒã³åºãããå€ãyieldããéåææäœãšããŠè¡šçŸã§ããŸãã
class ApiIterator {
constructor(apiUrls) {
this.apiUrls = apiUrls;
this.index = 0;
}
async next() {
if (this.index < this.apiUrls.length) {
const apiUrl = this.apiUrls[this.index];
this.index++;
try {
const response = await fetch(apiUrl);
const data = await response.json();
return { value: data, done: false };
} catch (error) {
console.error(`Error fetching ${apiUrl}:`, error);
return { value: undefined, done: false }; // Or handle the error differently
}
} else {
return { value: undefined, done: true };
}
}
[Symbol.asyncIterator]() {
return this;
}
}
// Example Usage:
const apiUrls = [
'https://api.example.com/data1',
'https://api.example.com/data2',
'https://api.example.com/data3',
];
async function processApiData() {
const apiIterator = new ApiIterator(apiUrls);
for await (const data of apiIterator) {
if (data) {
console.log('Received data:', data);
// Process the data (e.g., display it on a UI, save it to a database)
}
}
console.log('All data fetched.');
}
processApiData();
ãã®äŸã§ã¯ã`ApiIterator`ã¯ã©ã¹ãéåæAPIåŒã³åºããè¡ããçµæãyieldããããžãã¯ãã«ãã»ã«åããŠããŸãã`processApiData`颿°ã¯`for await...of`ã«ãŒãã䜿çšããŠã€ãã¬ãŒã¿ãæ¶è²»ããéåæããŒã¿ãœãŒã¹ãç°¡åã«å埩åŠçã§ããããšã瀺ããŠããŸãã
éåæãžã§ãã¬ãŒã¿
éåæãžã§ãã¬ãŒã¿ã¯ãéåæã€ãã¬ãŒã¿ãè¿ãç¹å¥ãªã¿ã€ãã®é¢æ°ã§ããããã¯`async function*`æ§æã䜿çšããŠå®çŸ©ãããŸããéåæãžã§ãã¬ãŒã¿ã¯ã`yield`ããŒã¯ãŒãã䜿çšããŠéåæã«å€ãyieldã§ããããã«ããããšã§ãéåæã€ãã¬ãŒã¿ã®äœæãç°¡çŽ åããŸãã
åã®`ApiIterator`ã®äŸãéåæãžã§ãã¬ãŒã¿ã«å€æããŠã¿ãŸãããïŒ
async function* apiGenerator(apiUrls) {
for (const apiUrl of apiUrls) {
try {
const response = await fetch(apiUrl);
const data = await response.json();
yield data;
} catch (error) {
console.error(`Error fetching ${apiUrl}:`, error);
// Consider re-throwing or yielding an error object
// yield { error: true, message: `Error fetching ${apiUrl}` };
}
}
}
// Example Usage:
const apiUrls = [
'https://api.example.com/data1',
'https://api.example.com/data2',
'https://api.example.com/data3',
];
async function processApiData() {
for await (const data of apiGenerator(apiUrls)) {
if (data) {
console.log('Received data:', data);
// Process the data
}
}
console.log('All data fetched.');
}
processApiData();
`apiGenerator`颿°ã¯ããã»ã¹ãåçåããŸããAPIã®URLãå埩åŠçããåã€ãã¬ãŒã·ã§ã³å ã§`fetch`åŒã³åºãã®çµæãawaitãã`yield`ããŒã¯ãŒãã䜿çšããŠããŒã¿ãyieldããŸãããã®ç°¡æœãªæ§æã¯ãã¯ã©ã¹ããŒã¹ã®`ApiIterator`ã¢ãããŒããšæ¯èŒããŠãå¯èªæ§ãå€§å¹ ã«åäžãããŸãã
éåæã¹ããªãŒã ã®é£æºãã¯ããã¯
éåæã€ãã¬ãŒã¿ãšéåæãžã§ãã¬ãŒã¿ã®çã®åã¯ãè€éã§å¹ççãªéåæã¯ãŒã¯ãããŒãäœæããããã«é£æºããã³æ§æã§ããèœåã«ãããŸãã飿ºããã»ã¹ãåçåããããã®ããã€ãã®ãã«ããŒãšã³ãžã³ãšãã¯ããã¯ãååšããŸããããããæ¢ã£ãŠã¿ãŸãããã
1. ãã§ã€ãã³ã°ãšæ§æ
éåæã€ãã¬ãŒã¿ã¯é£çµããããšãã§ããããŒã¿ãã¹ããªãŒã ãæµããéã«ããŒã¿ã®å€æããã£ã«ã¿ãªã³ã°ãå¯èœã«ããŸããããã¯ãLinux/Unixã®ãã€ãã©ã€ã³ã®æŠå¿µãä»ã®ããã°ã©ãã³ã°èšèªã®ãã€ãã«é¡äŒŒããŠããŸããè€æ°ã®éåæãžã§ãã¬ãŒã¿ãæ§æããããšã§ãè€éãªåŠçããžãã¯ãæ§ç¯ã§ããŸãã
// Example: Transforming the data after fetching
async function* transformData(asyncIterator) {
for await (const data of asyncIterator) {
if (data) {
const transformedData = data.map(item => ({ ...item, processed: true }));
yield transformedData;
}
}
}
// Example Usage: Composing multiple Async Generators
async function processDataPipeline(apiUrls) {
const rawData = apiGenerator(apiUrls);
const transformedData = transformData(rawData);
for await (const data of transformedData) {
console.log('Transformed data:', data);
// Further processing or display
}
}
processDataPipeline(apiUrls);
ãã®äŸã§ã¯ãããŒã¿ãååŸãã`apiGenerator`ãšãããŒã¿ã倿Žãã`transformData`ãžã§ãã¬ãŒã¿ãé£çµããŠããŸããããã«ãããããŒã¿ãå©çšå¯èœã«ãªãã«ã€ããŠãäžé£ã®å€æãããŒã¿ã«é©çšã§ããŸãã
2. éåæã€ãã¬ãŒã¿ãš`Promise.all`ããã³`Promise.allSettled`
`Promise.all`ãš`Promise.allSettled`ã¯ãè€æ°ã®Promiseãåæã«é£æºãããããã®åŒ·åãªããŒã«ã§ãããããã®ã¡ãœããã¯å ã éåæã€ãã¬ãŒã¿ã念é ã«çœ®ããŠèšèšããããã®ã§ã¯ãããŸããããããŒã¿ã¹ããªãŒã ã®åŠçãæé©åããããã«äœ¿çšã§ããŸãã
`Promise.all`ïŒãã¹ãŠã®æäœãæåããå¿ èŠãããå Žåã«äŸ¿å©ã§ããããããã®Promiseããªãžã§ã¯ãããããšãæäœå šäœããªãžã§ã¯ããããŸãã
async function processAllData(apiUrls) {
const promises = apiUrls.map(apiUrl => fetch(apiUrl).then(response => response.json()));
try {
const results = await Promise.all(promises);
console.log('All data fetched successfully:', results);
} catch (error) {
console.error('Error fetching data:', error);
}
}
//Example with Async Generator (slight modification needed)
async function* apiGeneratorWithPromiseAll(apiUrls) {
const promises = apiUrls.map(apiUrl => fetch(apiUrl).then(response => response.json()));
const results = await Promise.all(promises);
for(const result of results) {
yield result;
}
}
async function processApiDataWithPromiseAll() {
for await (const data of apiGeneratorWithPromiseAll(apiUrls)) {
console.log('Received Data:', data);
}
}
processApiDataWithPromiseAll();
`Promise.allSettled`ïŒãšã©ãŒãã³ããªã³ã°ã«ãããŠããå ç¢ã§ãããã¹ãŠã®Promiseã解決ïŒfulfilledãŸãã¯rejectedïŒãããã®ãåŸ ã¡ãåPromiseã®ã¹ããŒã¿ã¹ã瀺ãçµæã®é åãæäŸããŸããããã¯ãäžéšã®ãªã¯ãšã¹ãã倱æããŠãããŒã¿ãåéãããã·ããªãªã§åœ¹ç«ã¡ãŸãã
async function processAllSettledData(apiUrls) {
const promises = apiUrls.map(apiUrl => fetch(apiUrl).then(response => response.json()).catch(error => ({ error: true, message: error.message })));
const results = await Promise.allSettled(promises);
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`Data from ${apiUrls[index]}:`, result.value);
} else {
console.error(`Error from ${apiUrls[index]}:`, result.reason);
}
});
}
`Promise.allSettled`ã`asyncGenerator`ãšçµã¿åãããããšã§ãéåæã¹ããªãŒã åŠçãã€ãã©ã€ã³å ã§ã®ããè¯ããšã©ãŒãã³ããªã³ã°ãå¯èœã«ãªããŸãããã®ã¢ãããŒãã䜿çšããŠè€æ°ã®APIåŒã³åºãã詊ã¿ãäžéšã倱æããŠãæåãããã®ãåŠçããããšãã§ããŸãã
3. ã©ã€ãã©ãªãšãã«ããŒé¢æ°
ããã€ãã®ã©ã€ãã©ãªã¯ãéåæã€ãã¬ãŒã¿ã®æäœãç°¡çŽ åããããã®ãŠãŒãã£ãªãã£ããã«ããŒé¢æ°ãæäŸããŠããŸãããããã®ã©ã€ãã©ãªã¯ããã°ãã°æ¬¡ã®ãããªæ©èœãæäŸããŸãïŒ
- **ãããã¡ãªã³ã°ïŒ** çµæããããã¡ãªã³ã°ããŠããŒã¿ã®æµãã管çããŸãã
- **ãããã³ã°ããã£ã«ã¿ãªã³ã°ããªãã¥ãŒã·ã³ã°ïŒ** ã¹ããªãŒã ã«å€æãéèšãé©çšããŸãã
- **ã¹ããªãŒã ã®çµåïŒ** è€æ°ã®ã¹ããªãŒã ãããŒãžãŸãã¯é£çµããŸãã
- **ã¹ããããªã³ã°ãšãããŠã³ã¹ïŒ** ããŒã¿åŠçã®é床ãå¶åŸ¡ããŸãã
人æ°ã®éžæè¢ã«ã¯ä»¥äžãå«ãŸããŸãïŒ
- RxJS (Reactive Extensions for JavaScript)ïŒ éåæã¹ããªãŒã åŠçã®ããã®åºç¯ãªæ©èœãæäŸããã¹ããªãŒã ã®ãã£ã«ã¿ãªã³ã°ããããã³ã°ãçµåã®ããã®æŒç®åãå«ãŸããŸãããŸãã匷åãªãšã©ãŒãã³ããªã³ã°ãšäžŠè¡åŠçç®¡çæ©èœãåããŠããŸããRxJSã¯éåæã€ãã¬ãŒã¿ã«çŽæ¥åºã¥ããŠããããã§ã¯ãããŸãããããªã¢ã¯ãã£ãããã°ã©ãã³ã°ã®ããã®åæ§ã®æ©èœãæäŸããŸãã
- Iter-toolsïŒ ã€ãã¬ãŒã¿ãšéåæã€ãã¬ãŒã¿ãæ±ãããã«ç¹å¥ã«èšèšãããã©ã€ãã©ãªã§ãããã£ã«ã¿ãªã³ã°ããããã³ã°ãã°ã«ãŒãã³ã°ãªã©ã®äžè¬çãªã¿ã¹ã¯ã®ããã®å€ãã®ãŠãŒãã£ãªãã£é¢æ°ãæäŸããŸãã
- Node.js Streams API (Duplex/Transform Streams)ïŒ Node.js Streams APIã¯ãããŒã¿ã®ã¹ããªãŒãã³ã°ã®ããã®å ç¢ãªæ©èœãæäŸããŸããã¹ããªãŒã èªäœã¯éåæã€ãã¬ãŒã¿ã§ã¯ãããŸãããã倧ããªããŒã¿ãããŒã管çããããã«äžè¬çã«äœ¿çšãããŸããNode.jsã®`stream`ã¢ãžã¥ãŒã«ã¯ãããã¯ãã¬ãã·ã£ãŒãšããŒã¿å€æã®å¹ççãªåŠçã容æã«ããŸãã
ãããã®ã©ã€ãã©ãªã䜿çšããããšã§ãã³ãŒãã®è€éããå€§å¹ ã«åæžããå¯èªæ§ãåäžãããããšãã§ããŸãã
å®äžçã®ãŠãŒã¹ã±ãŒã¹ãšå¿çš
éåæã€ãã¬ãŒã¿ãã«ããŒé£æºãšã³ãžã³ã¯ãäžçäžã®ããŸããŸãªæ¥çã®å€ãã®ã·ããªãªã§å®çšçãªå¿çšãèŠãããŸãã
1. Webã¢ããªã±ãŒã·ã§ã³éçº
- ãªã¢ã«ã¿ã€ã ããŒã¿æŽæ°ïŒ WebSocketæ¥ç¶ããµãŒããŒã»ã³ãã€ãã³ãïŒSSEïŒããã®ããŒã¿ã¹ããªãŒã ãåŠçããŠãã©ã€ãã®æ ªäŸ¡ããœãŒã·ã£ã«ã¡ãã£ã¢ã®ãã£ãŒããã¹ããŒãã®ã¹ã³ã¢ãªã©ã衚瀺ããŸãã`async`ã®æ§è³ªã¯WebSocketãšå®å šã«äžèŽããŸãã
- ç¡éã¹ã¯ããŒã«ïŒ ãŠãŒã¶ãŒãã¹ã¯ããŒã«ããã«ã€ããŠããŒã¿ããã£ã³ã¯ã§ååŸã»ã¬ã³ããªã³ã°ããããã©ãŒãã³ã¹ãšãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãåäžãããŸããããã¯Eã³ããŒã¹ãã©ãããã©ãŒã ããœãŒã·ã£ã«ã¡ãã£ã¢ãµã€ãããã¥ãŒã¹ã¢ã°ãªã²ãŒã¿ãŒã§äžè¬çã§ãã
- ããŒã¿å¯èŠåïŒ å€§èŠæš¡ãªããŒã¿ã»ããããã®ããŒã¿ããªã¢ã«ã¿ã€ã ãŸãã¯ã»ãŒãªã¢ã«ã¿ã€ã ã§åŠçã»è¡šç€ºããŸããã¢ãã®ã€ã³ã¿ãŒãããïŒIoTïŒããã€ã¹ããã®ã»ã³ãµãŒããŒã¿ã®å¯èŠåãèããŠã¿ãŠãã ããã
2. ããã¯ãšã³ãéçºïŒNode.jsïŒ
- ããŒã¿åŠçãã€ãã©ã€ã³ïŒ å€§èŠæš¡ãªããŒã¿ã»ãããåŠçããããã®ETLïŒExtract, Transform, LoadïŒãã€ãã©ã€ã³ãæ§ç¯ããŸããäŸãã°ã忣ã·ã¹ãã ããã®ãã°ã®åŠçã顧客ããŒã¿ã®ã¯ãªãŒãã³ã°ãšå€æãªã©ã§ãã
- ãã¡ã€ã«åŠçïŒ ã¡ã¢ãªã®éè² è·ãé²ãããã«ã倧ããªãã¡ã€ã«ããã£ã³ã¯ã§èªã¿æžãããŸããããã¯ãµãŒããŒäžã§éåžžã«å€§ããªãã¡ã€ã«ãæ±ãå Žåã«æçã§ããéåæãžã§ãã¬ãŒã¿ã¯ããã¡ã€ã«ãäžåºŠã«äžè¡ãã€åŠçããã®ã«é©ããŠããŸãã
- ããŒã¿ããŒã¹ãšã®å¯Ÿè©±ïŒ ããŒã¿ããŒã¹ããã®ããŒã¿ã®å¹ççãªã¯ãšãªãšåŠçãå€§èŠæš¡ãªã¯ãšãªçµæãã¹ããªãŒãã³ã°åœ¢åŒã§æ±ããŸãã
- ãã€ã¯ããµãŒãã¹éä¿¡ïŒ éåæããŒã¿ãçæã»æ¶è²»ãããã€ã¯ããµãŒãã¹éã®éä¿¡ã調æŽããŸãã
3. ã¢ãã®ã€ã³ã¿ãŒãããïŒIoTïŒ
- ã»ã³ãµãŒããŒã¿éçŽïŒ è€æ°ã®ã»ã³ãµãŒãããªã¢ã«ã¿ã€ã ã§ããŒã¿ãåéã»åŠçããŸããæ§ã ãªç°å¢ã»ã³ãµãŒã補é è£ çœ®ããã®ããŒã¿ã¹ããªãŒã ãæ³åããŠã¿ãŠãã ããã
- ããã€ã¹å¶åŸ¡ïŒ IoTããã€ã¹ã«ã³ãã³ããéä¿¡ããéåæã§ã¹ããŒã¿ã¹ã®æŽæ°ãåä¿¡ããŸãã
- ãšããžã³ã³ãã¥ãŒãã£ã³ã°ïŒ ãããã¯ãŒã¯ã®ãšããžã§ããŒã¿ãåŠçããé å»¶ãåæžããå¿çæ§ãåäžãããŸãã
4. ãµãŒããŒã¬ã¹é¢æ°
- ããªã¬ãŒããŒã¹ã®åŠçïŒ ãã¡ã€ã«ã®ã¢ããããŒããããŒã¿ããŒã¹ã®å€æŽãªã©ã®ã€ãã³ãã«ãã£ãŠããªã¬ãŒãããããŒã¿ã¹ããªãŒã ãåŠçããŸãã
- ã€ãã³ãé§ååã¢ãŒããã¯ãã£ïŒ éåæã€ãã³ãã«å¿çããã€ãã³ãé§ååã·ã¹ãã ãæ§ç¯ããŸãã
éåæã¹ããªãŒã 管çã®ãã¹ããã©ã¯ãã£ã¹
éåæã€ãã¬ãŒã¿ãéåæãžã§ãã¬ãŒã¿ãããã³é£æºãã¯ããã¯ãå¹ççã«äœ¿çšããããã«ã¯ã以äžã®ãã¹ããã©ã¯ãã£ã¹ãèæ ®ããŠãã ããïŒ
1. ãšã©ãŒãã³ããªã³ã°
å ç¢ãªãšã©ãŒãã³ããªã³ã°ã¯éåžžã«éèŠã§ãã`async`颿°ãéåæãžã§ãã¬ãŒã¿å ã§`try...catch`ãããã¯ãå®è£ ããŠãäŸå€ãé©åã«åŠçããŠãã ããããšã©ãŒãåã¹ããŒããããäžæµã®ã³ã³ã·ã¥ãŒãã«ãšã©ãŒã·ã°ãã«ãçºä¿¡ããããšãæ€èšããŠãã ãããäžéšã®æäœã¯å€±æããå¯èœæ§ãããããä»ã¯ç¶ç¶ãã¹ãã·ããªãªãæ±ãããã«ã¯`Promise.allSettled`ã¢ãããŒãã䜿çšããŠãã ããã
async function* apiGeneratorWithRobustErrorHandling(apiUrls) {
for (const apiUrl of apiUrls) {
try {
const response = await fetch(apiUrl);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
yield data;
} catch (error) {
console.error(`Error fetching ${apiUrl}:`, error);
yield { error: true, message: `Failed to fetch ${apiUrl}` };
// Or, to stop iteration:
// return;
}
}
}
2. ãªãœãŒã¹ç®¡ç
ãããã¯ãŒã¯æ¥ç¶ããã¡ã€ã«ãã³ãã«ãªã©ã®ãªãœãŒã¹ãé©åã«ç®¡çããŠãã ãããäžèŠã«ãªã£ãæ¥ç¶ã¯éãããªãœãŒã¹ãè§£æŸããŠãã ããããšã©ãŒãçºçããå Žåã§ããªãœãŒã¹ãè§£æŸãããããã«ã`finally`ãããã¯ã®äœ¿çšãæ€èšããŠãã ããã
async function processDataWithResourceManagement(apiUrls) {
let response;
try {
for await (const data of apiGenerator(apiUrls)) {
if (data) {
console.log('Received data:', data);
}
}
} catch (error) {
console.error('An error occurred:', error);
} finally {
// Clean up resources (e.g., close database connections, release file handles)
// if (response) { response.close(); }
console.log('Resource cleanup completed.');
}
}
3. 䞊è¡åŠçã®å¶åŸ¡
ãªãœãŒã¹ã®æ¯æžãé²ãããã«ã䞊è¡åŠçã®ã¬ãã«ãå¶åŸ¡ããŠãã ãããç¹ã«å€éšAPIãæ±ãå Žåã¯ã次ã®ãããªãã¯ããã¯ã䜿çšããŠåæãªã¯ãšã¹ãã®æ°ãå¶éããŠãã ããïŒ
- ã¬ãŒãå¶éïŒ APIåŒã³åºãã«ã¬ãŒãå¶éãå®è£ ããŸãã
- ãã¥ãŒã€ã³ã°ïŒ ãã¥ãŒã䜿çšããŠãå¶åŸ¡ãããæ¹æ³ã§ãªã¯ãšã¹ããåŠçããŸãã`p-queue`ã®ãããªã©ã€ãã©ãªãããã管çããã®ã«åœ¹ç«ã¡ãŸãã
- ãããåŠçïŒ å°ããªãªã¯ãšã¹ãããããã«ãŸãšããŠããããã¯ãŒã¯ãªã¯ãšã¹ãã®æ°ãæžãããŸãã
// Example: Limiting Concurrency using a library like 'p-queue'
// (Requires installation: npm install p-queue)
import PQueue from 'p-queue';
const queue = new PQueue({ concurrency: 3 }); // Limit to 3 concurrent operations
async function fetchData(apiUrl) {
try {
const response = await fetch(apiUrl);
const data = await response.json();
return data;
} catch (error) {
console.error(`Error fetching ${apiUrl}:`, error);
throw error; // Re-throw to propagate the error
}
}
async function processDataWithConcurrencyLimit(apiUrls) {
const results = await Promise.all(apiUrls.map(url =>
queue.add(() => fetchData(url))
));
console.log('All results:', results);
}
4. ããã¯ãã¬ãã·ã£ãŒã®åŠç
ç¹ã«ããŒã¿ãæ¶è²»ããããããé«ãã¬ãŒãã§åŠçãããå Žåã¯ãããã¯ãã¬ãã·ã£ãŒãåŠçããŠãã ãããããã«ã¯ãããŒã¿ã®ãããã¡ãªã³ã°ãã¹ããªãŒã ã®äžæåæ¢ããŸãã¯ã¹ããããªã³ã°æè¡ã®é©çšãå«ãŸããŸããããã¯ããã¡ã€ã«ã¹ããªãŒã ããããã¯ãŒã¯ã¹ããªãŒã ãããã³ããŸããŸãªé床ã§ããŒã¿ãçæããä»ã®ããŒã¿ãœãŒã¹ãæ±ãå Žåã«ç¹ã«éèŠã§ãã
5. ãã¹ã
ãšã©ãŒã·ããªãªããšããžã±ãŒã¹ãããã©ãŒãã³ã¹ãå«ããéåæã³ãŒãã培åºçã«ãã¹ãããŠãã ãããéåæã€ãã¬ãŒã¿ããŒã¹ã®ãœãªã¥ãŒã·ã§ã³ã®ä¿¡é Œæ§ãšå¹çæ§ã確ä¿ããããã«ãåäœãã¹ããçµ±åãã¹ããããã©ãŒãã³ã¹ãã¹ãã®äœ¿çšãæ€èšããŠãã ãããå€éšãµãŒããŒã«äŸåããã«ãšããžã±ãŒã¹ããã¹ãããããã«ãAPIã¬ã¹ãã³ã¹ãã¢ãã¯åããŠãã ããã
6. ããã©ãŒãã³ã¹ã®æé©å
ã³ãŒãã®ãããã¡ã€ãªã³ã°ãè¡ããããã©ãŒãã³ã¹ãæé©åããŠãã ããã以äžã®ç¹ãèæ ®ããŠãã ããïŒ
- äžèŠãªæäœãæå°éã«æããïŒ éåæã¹ããªãŒã å ã®æäœãæé©åããŸãã
- `async`ãš`await`ãå¹ççã«äœ¿çšããïŒ æœåšçãªãªãŒããŒããããé¿ããããã«ã`async`ãš`await`ã®åŒã³åºãåæ°ãæå°éã«æããŸãã
- å¯èœãªå Žåã¯ããŒã¿ããã£ãã·ã¥ããïŒ é »ç¹ã«ã¢ã¯ã»ã¹ãããããŒã¿ãé«äŸ¡ãªèšç®ã®çµæããã£ãã·ã¥ããŸãã
- é©åãªããŒã¿æ§é ã䜿çšããïŒ å®è¡ããæäœã«æé©åãããããŒã¿æ§é ãéžæããŸãã
- ããã©ãŒãã³ã¹ã枬å®ããïŒ `console.time`ã`console.timeEnd`ãªã©ã®ããŒã«ããŸãã¯ããé«åºŠãªãããã¡ã€ãªã³ã°ããŒã«ã䜿çšããŠãããã©ãŒãã³ã¹ã®ããã«ããã¯ãç¹å®ããŸãã
é«åºŠãªãããã¯ãšãããªãæ¢æ±
ã³ã¢ã³ã³ã»ãããè¶ ããŠãéåæã€ãã¬ãŒã¿ããŒã¹ã®ãœãªã¥ãŒã·ã§ã³ãããã«æé©åããæŽç·Žãããããã®å€ãã®é«åºŠãªãã¯ããã¯ããããŸãã
1. ãã£ã³ã»ã«ãšã¢ããŒãã·ã°ãã«
éåææäœãé©åã«ãã£ã³ã»ã«ããã¡ã«ããºã ãå®è£ ããŠãã ããã`AbortController`ãš`AbortSignal` APIã¯ãfetchãªã¯ãšã¹ããä»ã®éåææäœã®ãã£ã³ã»ã«ãéç¥ããæšæºçãªæ¹æ³ãæäŸããŸãã
async function fetchDataWithAbort(apiUrl, signal) {
try {
const response = await fetch(apiUrl, { signal });
const data = await response.json();
return data;
} catch (error) {
if (error.name === 'AbortError') {
console.log('Fetch aborted.');
} else {
console.error(`Error fetching ${apiUrl}:`, error);
}
throw error;
}
}
async function processDataWithAbort(apiUrls) {
const controller = new AbortController();
const signal = controller.signal;
setTimeout(() => controller.abort(), 5000); // Abort after 5 seconds
try {
const promises = apiUrls.map(url => fetchDataWithAbort(url, signal));
const results = await Promise.allSettled(promises);
// Process results
} catch (error) {
console.error('An error occurred during processing:', error);
}
}
2. ã«ã¹ã¿ã éåæã€ãã¬ãŒã¿
ç¹å®ã®ããŒã¿ãœãŒã¹ãåŠçèŠä»¶ã®ããã«ãã«ã¹ã¿ã éåæã€ãã¬ãŒã¿ãäœæããŠãã ãããããã«ãããéåæã¹ããªãŒã ã®åäœã«å¯Ÿããæå€§éã®æè»æ§ãšå¶åŸ¡ãåŸãããŸããããã¯ãã«ã¹ã¿ã APIãã©ããããããã¬ã¬ã·ãŒãªéåæã³ãŒããšçµ±åãããããã®ã«åœ¹ç«ã¡ãŸãã
3. ãã©ãŠã¶ãžã®ããŒã¿ã®ã¹ããªãŒãã³ã°
`ReadableStream` APIã䜿çšããŠããµãŒããŒãããã©ãŠã¶ã«çŽæ¥ããŒã¿ãã¹ããªãŒãã³ã°ããŸããããã¯ãå€§èŠæš¡ãªããŒã¿ã»ããããªã¢ã«ã¿ã€ã ã®æŽæ°ã衚瀺ããå¿ èŠãããWebã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããã®ã«åœ¹ç«ã¡ãŸãã
4. Webã¯ãŒã«ãŒãšã®çµ±å
èšç®éçŽçãªæäœãWebã¯ãŒã«ãŒã«ãªãããŒãããŠãã¡ã€ã³ã¹ã¬ããã®ããããã³ã°ãé¿ããUIã®å¿çæ§ãåäžãããŸããéåæã€ãã¬ãŒã¿ã¯ãããã¯ã°ã©ãŠã³ãã§ããŒã¿ãåŠçããããã«Webã¯ãŒã«ãŒãšçµ±åã§ããŸãã
5. è€éãªãã€ãã©ã€ã³ã«ãããç¶æ 管ç
è€æ°ã®éåææäœã«ããã£ãŠã³ã³ããã¹ããç¶æããããã®ç¶æ 管çãã¯ããã¯ãå®è£ ããŠãã ãããããã¯ãè€æ°ã®ã¹ããããšããŒã¿å€æãå«ãè€éãªãã€ãã©ã€ã³ã«ãšã£ãŠéåžžã«éèŠã§ãã
çµè«
JavaScriptéåæã€ãã¬ãŒã¿ãã«ããŒé£æºãšã³ãžã³ã¯ãéåæããŒã¿ã¹ããªãŒã ã管çããããã®åŒ·åã§æè»ãªã¢ãããŒããæäŸããŸããéåæã€ãã¬ãŒã¿ãéåæãžã§ãã¬ãŒã¿ãããã³ããŸããŸãªé£æºãã¯ããã¯ã®ã³ã¢ã³ã³ã»ãããçè§£ããããšã§ãå ç¢ã§ã¹ã±ãŒã©ãã«ããã€å¹ççãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ã§ããŸãããã®ã¬ã€ãã§æŠèª¬ããããã¹ããã©ã¯ãã£ã¹ãåãå ¥ããããšã§ãã¯ãªãŒã³ã§ä¿å®å¯èœããã€é«æ§èœãªéåæJavaScriptã³ãŒããæžãããšãã§ããæçµçã«ã°ããŒãã«ãªã¢ããªã±ãŒã·ã§ã³ã®ãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãåäžãããããšãã§ããŸãã
éåæããã°ã©ãã³ã°ã¯çµ¶ããé²åããŠããŸããã¹ãã«ãåäžããç¶ããããã«ãECMAScriptãéåæã€ãã¬ãŒã¿ãéåæãžã§ãã¬ãŒã¿ã«é¢é£ããã©ã€ãã©ãªããã¬ãŒã ã¯ãŒã¯ã®ææ°ååãåžžã«ææ¡ããŠãã ãããéçºã¯ãŒã¯ãããŒãããã«æ¹åããããã«ãã¹ããªãŒã åŠçãéåææäœã«ç¹åããã©ã€ãã©ãªã調ã¹ãŠã¿ãããšãæ€èšããŠãã ããããããã®ãã¯ããã¯ãç¿åŸããããšã§ãçŸä»£ã®Webéçºã®èª²é¡ã«åãçµã¿ãã°ããŒãã«ãªèŠèŽè ã«å¯Ÿå¿ããé åçãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã®ååãªæºåãæŽããŸãã