JavaScriptã®éåæã³ã³ããã¹ãã®ã¡ã¢ãªç®¡çããã¹ã¿ãŒããã³ã³ããã¹ãã©ã€ããµã€ã¯ã«ãæé©åããŠãéåæã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ãšä¿¡é Œæ§ãåäžãããŸãããã
JavaScriptéåæã³ã³ããã¹ãã®ã¡ã¢ãªç®¡çïŒã³ã³ããã¹ãã©ã€ããµã€ã¯ã«ã®æé©å
éåæããã°ã©ãã³ã°ã¯çŸä»£ã®JavaScriptéçºã®åºç€ã§ãããå¿çæ§ãé«ãå¹ççãªã¢ããªã±ãŒã·ã§ã³ã®æ§ç¯ãå¯èœã«ããŸããããããéåææäœã«ãããã³ã³ããã¹ãã®ç®¡çã¯è€éã«ãªããã¡ã§ãæ éã«æ±ããªããšã¡ã¢ãªãªãŒã¯ãããã©ãŒãã³ã¹ã®åé¡ã«ã€ãªããå¯èœæ§ããããŸãããã®èšäºã§ã¯ãJavaScriptã®éåæã³ã³ããã¹ãã®è€éããæãäžããå ç¢ã§ã¹ã±ãŒã©ãã«ãªã¢ããªã±ãŒã·ã§ã³ã®ããã«ãã®ã©ã€ããµã€ã¯ã«ãæé©åããããšã«çŠç¹ãåœãŠãŸãã
JavaScriptã«ãããéåæã³ã³ããã¹ãã®çè§£
åæçãªJavaScriptã³ãŒãã§ã¯ãã³ã³ããã¹ãïŒå€æ°ã颿°åŒã³åºããå®è¡ç¶æ ïŒã®ç®¡çã¯ç°¡åã§ãã颿°ãçµäºãããšããã®ã³ã³ããã¹ãã¯éåžžè§£æŸãããã¬ããŒãžã³ã¬ã¯ã¿ãã¡ã¢ãªãååã§ããããã«ãªããŸããããããéåææäœã¯è€éãã®å±€ã远å ããŸããAPIããã®ããŒã¿ååŸããŠãŒã¶ãŒã€ãã³ãã®åŠçãªã©ã®éåæã¿ã¹ã¯ã¯ãå¿ ãããããã«å®äºããããã§ã¯ãããŸããããããã¯ãã°ãã°ã³ãŒã«ããã¯ãPromiseããŸãã¯async/awaitã䌎ããã¯ããŒãžã£ãäœæããåšå²ã®ã¹ã³ãŒãå ã®å€æ°ãžã®åç §ãä¿æããå¯èœæ§ããããŸããããã«ãããæå³ããã³ã³ããã¹ãã®äžéšãå¿ èŠä»¥äžã«é·ãåç¶ããã¡ã¢ãªãªãŒã¯ã«ã€ãªããããšããããŸãã
ã¯ããŒãžã£ã®åœ¹å²
ã¯ããŒãžã£ã¯éåæJavaScriptã«ãããŠéèŠãªåœ¹å²ãæãããŸããã¯ããŒãžã£ãšã¯ã颿°ãšãã®åšå²ã®ç¶æ ïŒã¬ãã·ã«ã«ç°å¢ïŒãžã®åç §ãšãçµã¿åããããã®ã§ããèšãæããã°ãã¯ããŒãžã£ã¯å åŽã®é¢æ°ããå€åŽã®é¢æ°ã®ã¹ã³ãŒãã«ã¢ã¯ã»ã¹ããææ®µãæäŸããŸããéåææäœãã³ãŒã«ããã¯ãPromiseã«äŸåããå Žåã芪ã¹ã³ãŒãã®å€æ°ã«ã¢ã¯ã»ã¹ããããã«ã¯ããŒãžã£ããã°ãã°äœ¿çšãããŸãããããã®ã¯ããŒãžã£ãããã¯ãäžèŠã«ãªã£ã倧ããªãªããžã§ã¯ããããŒã¿æ§é ãžã®åç §ãä¿æãç¶ãããšãã¡ã¢ãªæ¶è²»ã«å€§ããªåœ±é¿ãäžããå¯èœæ§ããããŸãã
次ã®äŸãèããŠã¿ãŸãããïŒ
function fetchData(url) {
const largeData = new Array(1000000).fill('some data'); // Simulate a large dataset
return new Promise((resolve, reject) => {
setTimeout(() => {
// Simulate fetching data from an API
const result = `Data from ${url}`; // Uses url from the outer scope
resolve(result);
}, 1000);
});
}
async function processData() {
const data = await fetchData('https://example.com/api/data');
console.log(data);
// largeData is still in scope here, even if it's not used directly
}
processData();
ãã®äŸã§ã¯ã`processData`ãååŸããããŒã¿ããã°ã«åºåããåŸã§ãã`fetchData`å ã®`setTimeout`ã³ãŒã«ããã¯ã«ãã£ãŠäœæãããã¯ããŒãžã£ã®ããã«ã`largeData`ã¯ã¹ã³ãŒãå ã«æ®ããŸãã`fetchData`ãè€æ°ååŒã³åºããããšã`largeData`ã®è€æ°ã®ã€ã³ã¹ã¿ã³ã¹ãã¡ã¢ãªå ã«ä¿æãããã¡ã¢ãªãªãŒã¯ã«ã€ãªããå¯èœæ§ããããŸãã
éåæJavaScriptã«ãããã¡ã¢ãªãªãŒã¯ã®ç¹å®
éåæJavaScriptã«ãããã¡ã¢ãªãªãŒã¯ã®æ€åºã¯å°é£ãªå ŽåããããŸãã以äžã«ãäžè¬çãªããŒã«ãšãã¯ããã¯ãããã€ã玹ä»ããŸãïŒ
- ãã©ãŠã¶éçºè ããŒã«ïŒ ã»ãšãã©ã®ã¢ãã³ãã©ãŠã¶ã¯ãã¡ã¢ãªäœ¿çšéããããã¡ã€ãªã³ã°ããããã®åŒ·åãªéçºè ããŒã«ãæäŸããŠããŸããäŸãã°ãChrome DevToolsã䜿çšãããšãããŒãã¹ãããã·ã§ããã®ååŸãã¡ã¢ãªå²ãåœãŠã¿ã€ã ã©ã€ã³ã®èšé²ãã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãããŠããªããªããžã§ã¯ãã®ç¹å®ãå¯èœã§ããæœåšçãªãªãŒã¯ã調æ»ããéã«ã¯ãä¿æãµã€ãºïŒretained sizeïŒãšã³ã³ã¹ãã©ã¯ã¿ã®åã«æ³šæããŠãã ããã
- Node.jsã¡ã¢ãªãããã¡ã€ã©ïŒ Node.jsã¢ããªã±ãŒã·ã§ã³ã§ã¯ã`heapdump`ã`v8-profiler`ã®ãããªããŒã«ã䜿çšããŠããŒãã¹ãããã·ã§ããããã£ããã£ããã¡ã¢ãªäœ¿çšéãåæã§ããŸããNode.jsã€ã³ã¹ãã¯ã¿ïŒ`node --inspect`ïŒããChrome DevToolsã«äŒŒããããã°ã€ã³ã¿ãŒãã§ãŒã¹ãæäŸããŸãã
- ããã©ãŒãã³ã¹ç£èŠããŒã«ïŒ New RelicãDatadogãSentryãªã©ã®ã¢ããªã±ãŒã·ã§ã³ããã©ãŒãã³ã¹ç£èŠïŒAPMïŒããŒã«ã¯ãæéçµéã«äŒŽãã¡ã¢ãªäœ¿çšéã®åŸåã«é¢ããæŽå¯ãæäŸã§ããŸãããããã®ããŒã«ã¯ããã¿ãŒã³ã®ç¹å®ããã¡ã¢ãªãªãŒã¯ã«å¯äžããŠããå¯èœæ§ã®ããã³ãŒãé åã®ç¹å®ã«åœ¹ç«ã¡ãŸãã
- ã³ãŒãã¬ãã¥ãŒïŒ 宿çãªã³ãŒãã¬ãã¥ãŒã¯ãæœåšçãªã¡ã¢ãªç®¡çã®åé¡ãæ·±å»åããåã«ç¹å®ããã®ã«åœ¹ç«ã¡ãŸããã¯ããŒãžã£ãã€ãã³ããªã¹ããéåææäœã§äœ¿çšãããããŒã¿æ§é ã«ç¹ã«æ³šæãæã£ãŠãã ããã
ã¡ã¢ãªãªãŒã¯ã®äžè¬çãªå å
JavaScriptã¢ããªã±ãŒã·ã§ã³ãã¡ã¢ãªãªãŒã¯ã«æ©ãŸãããŠããå¯èœæ§ã瀺ããããã€ãã®å åã以äžã«ç€ºããŸãïŒ
- ã¡ã¢ãªäœ¿çšéã®æ®µéçãªå¢å ïŒ ã¢ããªã±ãŒã·ã§ã³ãç©æ¥µçã«ã¿ã¹ã¯ãå®è¡ããŠããªããšãã§ããã¡ã¢ãªæ¶è²»éãæéãšãšãã«çå®ã«å¢å ããŸãã
- ããã©ãŒãã³ã¹ã®äœäžïŒ é·æéå®è¡ããã«ã€ããŠãã¢ããªã±ãŒã·ã§ã³ãé ããªããå¿çæ§ãäœäžããŸãã
- é »ç¹ãªã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãµã€ã¯ã«ïŒ ã¬ããŒãžã³ã¬ã¯ã¿ãããé »ç¹ã«å®è¡ãããããã«ãªããã¡ã¢ãªã®ååã«èŠåŽããŠããããšã瀺ããŸãã
- ã¢ããªã±ãŒã·ã§ã³ã®ã¯ã©ãã·ã¥ïŒ 極端ãªå Žåãã¡ã¢ãªãªãŒã¯ã¯ã¡ã¢ãªäžè¶³ãšã©ãŒã«ããã¢ããªã±ãŒã·ã§ã³ã®ã¯ã©ãã·ã¥ã«ã€ãªããå¯èœæ§ããããŸãã
éåæã³ã³ããã¹ãã©ã€ããµã€ã¯ã«ã®æé©å
éåæã³ã³ããã¹ãã®ã¡ã¢ãªç®¡çã®èª²é¡ãçè§£ãããšããã§ãã³ã³ããã¹ãã©ã€ããµã€ã¯ã«ãæé©åããããã®ããã€ãã®æŠç¥ãæ¢ã£ãŠã¿ãŸãããïŒ
1. ã¯ããŒãžã£ã®ã¹ã³ãŒããæå°åãã
ã¯ããŒãžã£ã®ã¹ã³ãŒããå°ããã»ã©ãæ¶è²»ããã¡ã¢ãªã¯å°ãªããªããŸããã¯ããŒãžã£ã§äžèŠãªå€æ°ããã£ããã£ããªãããã«ããŸãããã代ããã«ãéåææäœã«å³å¯ã«å¿ èŠãªããŒã¿ã®ã¿ãæž¡ããŸãã
äŸïŒ
æªãäŸïŒ
function processUserData(user) {
const userData = { ...user, extraData: 'some extra info' }; // Create a new object
setTimeout(() => {
console.log(`Processing user: ${userData.name}`); // Access userData
}, 1000);
}
ãã®äŸã§ã¯ã`setTimeout`ã³ãŒã«ããã¯å ã§`name`ããããã£ãã䜿çšãããŠããªãã«ããããããã`userData`ãªããžã§ã¯ãå šäœãã¯ããŒãžã£ã«ãã£ããã£ãããŸãã
è¯ãäŸïŒ
function processUserData(user) {
const userData = { ...user, extraData: 'some extra info' };
const userName = userData.name; // Extract the name
setTimeout(() => {
console.log(`Processing user: ${userName}`); // Access only userName
}, 1000);
}
ãã®æé©åãããããŒãžã§ã³ã§ã¯ãã¯ããŒãžã£ã«ã¯`userName`ã®ã¿ããã£ããã£ãããã¡ã¢ãªãããããªã³ããåæžãããŸãã
2. 埪ç°åç §ãæã¡åã
埪ç°åç §ã¯ã2ã€ä»¥äžã®ãªããžã§ã¯ããäºãã«åç §ãåãããšã§çºçããããããã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãããã®ã劚ããŸããããã¯éåæJavaScriptã§ã¯ãç¹ã«ã€ãã³ããªã¹ããè€éãªããŒã¿æ§é ãæ±ãéã«ããããåé¡ã§ãã
äŸïŒ
class MyObject {
constructor() {
this.eventListeners = [];
}
addListener(listener) {
this.eventListeners.push(listener);
}
removeListener(listener) {
this.eventListeners = this.eventListeners.filter(l => l !== listener);
}
doSomethingAsync() {
const listener = () => {
console.log('Something happened!');
this.doSomethingElse(); // Circular reference: listener references this
};
this.addListener(listener);
setTimeout(() => {
this.removeListener(listener);
}, 1000);
}
doSomethingElse() {
console.log('Doing something else.');
}
}
const myObject = new MyObject();
myObject.doSomethingAsync();
ãã®äŸã§ã¯ã`doSomethingAsync`å ã®`listener`颿°ã`this`ïŒ`MyObject`ã€ã³ã¹ã¿ã³ã¹ïŒãžã®åç §ããã£ããã£ããŸãã`MyObject`ã€ã³ã¹ã¿ã³ã¹ã`eventListeners`é åãä»ããŠ`listener`ãžã®åç §ãä¿æããŠããŸããããã«ãã埪ç°åç §ãäœæããã`setTimeout`ã³ãŒã«ããã¯ãå®è¡ãããåŸã§ãã`MyObject`ã€ã³ã¹ã¿ã³ã¹ãš`listener`ã®äž¡æ¹ãã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãããã®ãé²ããŸãããªã¹ããŒã¯`eventListeners`é åããåé€ãããŸãããã¯ããŒãžã£èªäœã¯äŸç¶ãšããŠ`this`ãžã®åç §ãä¿æããŠããŸãã
解決çïŒ äžèŠã«ãªã£ãåŸã§åç §ãæç€ºçã«`null`ãŸãã¯undefinedã«èšå®ããããšã§ã埪ç°åç §ãæã¡åããŸãã
class MyObject {
constructor() {
this.eventListeners = [];
}
addListener(listener) {
this.eventListeners.push(listener);
}
removeListener(listener) {
this.eventListeners = this.eventListeners.filter(l => l !== listener);
}
doSomethingAsync() {
let listener = () => {
console.log('Something happened!');
this.doSomethingElse();
listener = null; // Break the circular reference
};
this.addListener(listener);
setTimeout(() => {
this.removeListener(listener);
}, 1000);
}
doSomethingElse() {
console.log('Doing something else.');
}
}
const myObject = new MyObject();
myObject.doSomethingAsync();
äžèšã®è§£æ±ºçã¯åŸªç°åç §ãæã¡åãããã«èŠãããããããŸãããã`setTimeout`å ã®ãªã¹ããŒã¯äŸç¶ãšããŠå ã®`listener`颿°ãåç §ããŠãããããã`this`ãåç §ããŠããŸããããå ç¢ãªè§£æ±ºçã¯ããªã¹ããŒå ã§çŽæ¥`this`ããã£ããã£ããããšãé¿ããããšã§ãã
class MyObject {
constructor() {
this.eventListeners = [];
}
addListener(listener) {
this.eventListeners.push(listener);
}
removeListener(listener) {
this.eventListeners = this.eventListeners.filter(l => l !== listener);
}
doSomethingAsync() {
const self = this; // Capture 'this' in a separate variable
const listener = () => {
console.log('Something happened!');
self.doSomethingElse(); // Use the captured 'self'
};
this.addListener(listener);
setTimeout(() => {
this.removeListener(listener);
}, 1000);
}
doSomethingElse() {
console.log('Doing something else.');
}
}
const myObject = new MyObject();
myObject.doSomethingAsync();
ããã§ããã€ãã³ããªã¹ããŒãé·æéã¢ã¿ããããããŸãŸã§ããå Žåãåé¡ã¯å®å šã«ã¯è§£æ±ºãããŸãããæãä¿¡é Œæ§ã®é«ãã¢ãããŒãã¯ã`MyObject`ã€ã³ã¹ã¿ã³ã¹ãçŽæ¥åç §ããã¯ããŒãžã£ãå®å šã«é¿ããã€ãã³ãçºè¡ã¡ã«ããºã ã䜿çšããããšã§ãã
3. ã€ãã³ããªã¹ãã®ç®¡ç
ã€ãã³ããªã¹ãã¯ãé©åã«åé€ãããªãå Žåãã¡ã¢ãªãªãŒã¯ã®äžè¬çãªåå ãšãªããŸããèŠçŽ ããªããžã§ã¯ãã«ã€ãã³ããªã¹ããã¢ã¿ãããããšããªã¹ãã¯æç€ºçã«åé€ãããããèŠçŽ /ãªããžã§ã¯ããç Žæ£ããããŸã§ã¢ã¯ãã£ããªãŸãŸã§ãããªã¹ãã®åé€ãå¿ãããšãæéãšãšãã«èç©ãããã¡ã¢ãªãæ¶è²»ããããã©ãŒãã³ã¹ã®åé¡ãåŒãèµ·ããå¯èœæ§ããããŸãã
äŸïŒ
const button = document.getElementById('myButton');
function handleClick() {
console.log('Button clicked!');
}
button.addEventListener('click', handleClick);
// PROBLEM: The event listener is never removed!
解決çïŒ äžèŠã«ãªã£ãã€ãã³ããªã¹ãã¯å¿ ãåé€ããŠãã ããã
const button = document.getElementById('myButton');
function handleClick() {
console.log('Button clicked!');
button.removeEventListener('click', handleClick); // Remove the listener
}
button.addEventListener('click', handleClick);
// Alternatively, remove the listener after a certain condition:
setTimeout(() => {
button.removeEventListener('click', handleClick);
}, 5000);
DOMèŠçŽ ã®ã¬ããŒãžã³ã¬ã¯ã·ã§ã³ã劚ããããšãªãããããã®èŠçŽ ã«ããŒã¿ãé¢é£ä»ããå¿ èŠãããå Žåã¯ã`WeakMap`ã䜿çšããŠã€ãã³ããªã¹ããä¿åããããšãæ€èšããŠãã ããã
4. WeakRefãšFinalizationRegistryã®äœ¿çšïŒäžçŽïŒ
ããè€éãªã·ããªãªã§ã¯ã`WeakRef`ãš`FinalizationRegistry`ã䜿çšããŠããªããžã§ã¯ãã®ã©ã€ããµã€ã¯ã«ãç£èŠãããªããžã§ã¯ããã¬ããŒãžã³ã¬ã¯ã·ã§ã³ããããšãã«ã¯ãªãŒã³ã¢ããã¿ã¹ã¯ãå®è¡ã§ããŸãã`WeakRef`ã䜿çšãããšããªããžã§ã¯ããã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãããã®ã劚ããããšãªãããã®ãªããžã§ã¯ããžã®åç §ãä¿æã§ããŸãã`FinalizationRegistry`ã䜿çšãããšããªããžã§ã¯ããã¬ããŒãžã³ã¬ã¯ã·ã§ã³ããããšãã«å®è¡ãããã³ãŒã«ããã¯ãç»é²ã§ããŸãã
äŸïŒ
const registry = new FinalizationRegistry(heldValue => {
console.log(`Object with value ${heldValue} was garbage collected.`);
});
let obj = { data: 'some data' };
const weakRef = new WeakRef(obj);
registry.register(obj, obj.data); // Register the object with the registry
obj = null; // Remove the strong reference to the object
// At some point in the future, the garbage collector will reclaim the memory used by the object,
// and the callback in the FinalizationRegistry will be executed.
ãŠãŒã¹ã±ãŒã¹ïŒ
- ãã£ãã·ã¥ç®¡çïŒ `WeakRef`ã䜿çšããŠã察å¿ãããªããžã§ã¯ãã䜿çšãããªããªã£ããšãã«ãšã³ããªãèªåçã«åé€ãããã£ãã·ã¥ãå®è£ ã§ããŸãã
- ãªãœãŒã¹ã®ã¯ãªãŒã³ã¢ããïŒ `FinalizationRegistry`ã䜿çšããŠããªããžã§ã¯ããã¬ããŒãžã³ã¬ã¯ã·ã§ã³ããããšãã«ãªãœãŒã¹ïŒãã¡ã€ã«ãã³ãã«ããããã¯ãŒã¯æ¥ç¶ãªã©ïŒãè§£æŸã§ããŸãã
éèŠãªèæ ®äºé ïŒ
- ã¬ããŒãžã³ã¬ã¯ã·ã§ã³ã¯é決å®çã§ããããã`FinalizationRegistry`ã®ã³ãŒã«ããã¯ãç¹å®ã®æéã«å®è¡ãããããšã«äŸåããããšã¯ã§ããŸããã
- `WeakRef`ãš`FinalizationRegistry`ã¯ã³ãŒããè€éã«ããå¯èœæ§ããããããæ§ããã«äœ¿çšããŠãã ããã
5. ã°ããŒãã«å€æ°ãé¿ãã
ã°ããŒãã«å€æ°ã¯å¯¿åœãé·ããã¢ããªã±ãŒã·ã§ã³ãçµäºãããŸã§ã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãããŸãããäžæçã«ããå¿ èŠãšãããªã倧ããªãªããžã§ã¯ããããŒã¿æ§é ãæ ŒçŽããããã«ã°ããŒãã«å€æ°ã䜿çšããã®ã¯é¿ããŠãã ããã代ããã«ã颿°ãã¢ãžã¥ãŒã«å ã§ããŒã«ã«å€æ°ã䜿çšããŸãããããã¯ã¹ã³ãŒãå€ã«ãªããšã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãããŸãã
äŸïŒ
æªãäŸïŒ
// Global variable
let myLargeArray = new Array(1000000).fill('some data');
function processData() {
// ... use myLargeArray
}
processData();
è¯ãäŸïŒ
function processData() {
// Local variable
const myLargeArray = new Array(1000000).fill('some data');
// ... use myLargeArray
}
processData();
2çªç®ã®äŸã§ã¯ã`myLargeArray`ã¯`processData`å ã®ããŒã«ã«å€æ°ãªã®ã§ã`processData`ã®å®è¡ãçµäºãããšã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãããŸãã
6. ãªãœãŒã¹ãæç€ºçã«è§£æŸãã
å Žåã«ãã£ãŠã¯ãéåææäœã«ãã£ãŠä¿æãããŠãããªãœãŒã¹ãæç€ºçã«è§£æŸããå¿ èŠããããŸããäŸãã°ãããŒã¿ããŒã¹æ¥ç¶ããã¡ã€ã«ãã³ãã«ã䜿çšããŠããå Žåã䜿ãçµãã£ãããããéããã¹ãã§ããããã¯ãªãœãŒã¹ãªãŒã¯ãé²ããã¢ããªã±ãŒã·ã§ã³å šäœã®å®å®æ§ãåäžãããã®ã«åœ¹ç«ã¡ãŸãã
äŸïŒ
const fs = require('fs');
async function readFileAsync(filePath) {
return new Promise((resolve, reject) => {
fs.readFile(filePath, (err, data) => {
if (err) {
reject(err);
return;
}
resolve(data);
});
});
}
async function processFile(filePath) {
let fileHandle = null;
try {
fileHandle = await fs.promises.open(filePath, 'r');
const data = await readFileAsync(filePath); // Or fileHandle.readFile()
console.log(data.toString());
} catch (error) {
console.error('Error reading file:', error);
} finally {
if (fileHandle) {
await fileHandle.close(); // Explicitly close the file handle
console.log('File handle closed.');
}
}
}
processFile('myFile.txt');
`finally`ãããã¯ã¯ããã¡ã€ã«åŠçäžã«ãšã©ãŒãçºçããå Žåã§ãããã¡ã€ã«ãã³ãã«ãåžžã«éããããããšãä¿èšŒããŸãã
7. éåæã€ãã¬ãŒã¿ãšãžã§ãã¬ãŒã¿ã®äœ¿çš
éåæã€ãã¬ãŒã¿ãšãžã§ãã¬ãŒã¿ã¯ã倧éã®ããŒã¿ãéåæã§åŠçããããã®ããå¹ççãªæ¹æ³ãæäŸããŸããããŒã¿ããã£ã³ã¯ã§åŠçã§ãããããã¡ã¢ãªæ¶è²»ãåæžããå¿çæ§ãåäžãããããšãã§ããŸãã
äŸïŒ
async function* generateData() {
for (let i = 0; i < 100; i++) {
await new Promise(resolve => setTimeout(resolve, 10)); // Simulate asynchronous operation
yield i;
}
}
async function processData() {
for await (const item of generateData()) {
console.log(item);
}
}
processData();
ãã®äŸã§ã¯ã`generateData`颿°ã¯éåæã§ããŒã¿ãçæïŒyieldïŒããéåæãžã§ãã¬ãŒã¿ã§ãã`processData`颿°ã¯`for await...of`ã«ãŒãã䜿çšããŠçæãããããŒã¿ãå埩åŠçããŸããããã«ãããããŒã¿ã»ããå šäœãäžåºŠã«ã¡ã¢ãªã«ããŒãããããšãªããããŒã¿ããã£ã³ã¯ã§åŠçã§ããŸãã
8. éåææäœã®ã¹ããããªã³ã°ãšãããŠã³ã¹
ãŠãŒã¶ãŒå ¥åã®åŠçãAPIããã®ããŒã¿ååŸãªã©ãé »ç¹ãªéåææäœãæ±ãå Žåãã¹ããããªã³ã°ãšãããŠã³ã¹ã¯ã¡ã¢ãªæ¶è²»ãåæžããããã©ãŒãã³ã¹ãåäžãããã®ã«åœ¹ç«ã¡ãŸããã¹ããããªã³ã°ã¯é¢æ°ã®å®è¡é »åºŠãå¶éãããããŠã³ã¹ã¯æåŸã®åŒã³åºãããäžå®æéãçµéãããŸã§é¢æ°ã®å®è¡ãé å»¶ãããŸãã
äŸïŒãããŠã³ã¹ïŒïŒ
function debounce(func, delay) {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
function handleInputChange(event) {
console.log('Input changed:', event.target.value);
// Perform asynchronous operation here (e.g., search API call)
}
const debouncedHandleInputChange = debounce(handleInputChange, 300); // Debounce for 300ms
const inputElement = document.getElementById('myInput');
inputElement.addEventListener('input', debouncedHandleInputChange);
ãã®äŸã§ã¯ã`debounce`颿°ã`handleInputChange`颿°ãã©ããããŠããŸãããããŠã³ã¹ããã颿°ã¯ã300ããªç§éäœãæäœããªãå Žåã«ã®ã¿å®è¡ãããŸããããã«ãããéå°ãªAPIåŒã³åºããé²ããã¡ã¢ãªæ¶è²»ãåæžããŸãã
9. ã©ã€ãã©ãªããã¬ãŒã ã¯ãŒã¯ã®äœ¿çšãæ€èšãã
å€ãã®JavaScriptã©ã€ãã©ãªããã¬ãŒã ã¯ãŒã¯ã¯ãéåææäœã管çããã¡ã¢ãªãªãŒã¯ãé²ãããã®çµã¿èŸŒã¿ã¡ã«ããºã ãæäŸããŠããŸããäŸãã°ãReactã®useEffectããã¯ã䜿çšãããšãå¯äœçšãç°¡åã«ç®¡çããã³ã³ããŒãã³ããã¢ã³ããŠã³ãããããšãã«ã¯ãªãŒã³ã¢ããã§ããŸããåæ§ã«ãAngularã®RxJSã©ã€ãã©ãªã¯ãéåæããŒã¿ã¹ããªãŒã ãåŠçãããµãã¹ã¯ãªãã·ã§ã³ã管çããããã®åŒ·åãªãªãã¬ãŒã¿ã»ãããæäŸããŸãã
äŸïŒReactã®useEffectïŒïŒ
import React, { useState, useEffect } from 'react';
function MyComponent() {
const [data, setData] = useState(null);
useEffect(() => {
let isMounted = true; // Track component mount state
async function fetchData() {
const response = await fetch('https://example.com/api/data');
const result = await response.json();
if (isMounted) {
setData(result);
}
}
fetchData();
return () => {
// Cleanup function
isMounted = false; // Prevent state updates on unmounted component
// Cancel any pending asynchronous operations here
};
}, []); // Empty dependency array means this effect runs only once on mount
return (
{data ? Data: {data.value}
: Loading...
}
);
}
export default MyComponent;
`useEffect`ããã¯ã¯ãã³ã³ããŒãã³ãããŸã ããŠã³ããããŠããå Žåã«ã®ã¿ç¶æ ãæŽæ°ããããšãä¿èšŒããŸããã¯ãªãŒã³ã¢ãã颿°ã¯`isMounted`ã`false`ã«èšå®ããã³ã³ããŒãã³ããã¢ã³ããŠã³ããããåŸã®ãããªãç¶æ æŽæ°ãé²ããŸããããã«ãããã³ã³ããŒãã³ããç Žæ£ãããåŸã«éåææäœãå®äºãããšãã«çºçãããã¡ã¢ãªãªãŒã¯ãé²ããŸãã
çµè«
å¹ççãªã¡ã¢ãªç®¡çã¯ãç¹ã«éåææäœãæ±ãéã«ãå ç¢ã§ã¹ã±ãŒã©ãã«ãªJavaScriptã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã«äžå¯æ¬ ã§ããéåæã³ã³ããã¹ãã®è€éããçè§£ããæœåšçãªã¡ã¢ãªãªãŒã¯ãç¹å®ãããã®èšäºã§èª¬æããæé©åãã¯ããã¯ãå®è£ ããããšã§ãã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ãšä¿¡é Œæ§ãå€§å¹ ã«åäžãããããšãã§ããŸãããããã¡ã€ãªã³ã°ããŒã«ã䜿çšãã培åºçãªã³ãŒãã¬ãã¥ãŒã宿œãã`WeakRef`ã`FinalizationRegistry`ã®ãããªã¢ãã³ãªJavaScriptã®æ©èœã掻çšããŠãã¢ããªã±ãŒã·ã§ã³ãã¡ã¢ãªå¹çã«åªããããã©ãŒãã³ã¹ãé«ãããšã確èªããããšãå¿ããªãã§ãã ããã