JavaScriptã®Async Local StorageïŒALSïŒã掻çšãã广çãªãªã¯ãšã¹ãã³ã³ããã¹ã管çãæ¢ããŸããéåææäœéã§ããŒã¿ã远跡ã»å ±æããããŒã¿äžè²«æ§ã®ç¢ºä¿ãšãããã°ã®ç°¡çŽ åãå®çŸããæ¹æ³ãåŠã³ãŸãããã
JavaScriptã®Async Local Storage: ãªã¯ãšã¹ãã³ã³ããã¹ã管çã®ãã¹ã¿ãŒ
çŸä»£ã®JavaScriptéçºãç¹ã«å€æ°ã®åæãªã¯ãšã¹ããåŠçããNode.jsç°å¢ã§ã¯ãéåææäœå šäœã§ã³ã³ããã¹ãã广çã«ç®¡çããããšãæãéèŠã«ãªããŸããåŸæ¥ã®ã¢ãããŒãã¯ãã°ãã°äžååã§ãè€éãªã³ãŒããæœåšçãªããŒã¿äžæŽåã«ã€ãªãããŸããããã§JavaScriptã®Async Local StorageïŒALSïŒãèŒããæŸã¡ãŸããALSã¯ãç¹å®ã®éåæå®è¡ã³ã³ããã¹ãã«ããŒã«ã«ãªããŒã¿ãä¿åããã³ååŸããããã®åŒ·åãªã¡ã«ããºã ãæäŸããŸãããã®èšäºã§ã¯ãJavaScriptã¢ããªã±ãŒã·ã§ã³ã§å ç¢ãªãªã¯ãšã¹ãã³ã³ããã¹ã管çã®ããã«ALSãçè§£ããæŽ»çšããããã®å æ¬çãªã¬ã€ããæäŸããŸãã
Async Local Storage (ALS) ãšã¯äœãïŒ
Async Local Storageã¯ãNode.jsã®ã³ã¢ã¢ãžã¥ãŒã«ãšããŠå©çšå¯èœã§ããïŒv13.10.0ã§å°å ¥ããããã®åŸå®å®åïŒãWebãªã¯ãšã¹ãã®åŠçãªã©ã®éåææäœã®ã©ã€ãã¿ã€ã å šäœã§ã¢ã¯ã»ã¹å¯èœãªããŒã¿ãä¿åã§ããŸããããã¯ã¹ã¬ããããŒã«ã«ã¹ãã¬ãŒãžã¡ã«ããºã ã®ãããªãã®ã§ãããJavaScriptã®éåæçãªæ§è³ªã«é©å¿ããŠããŸããããã«ããããã¹ãŠã®é¢æ°ã«åŒæ°ãšããŠæç€ºçã«ã³ã³ããã¹ããæž¡ãããšãªããè€æ°ã®éåæåŒã³åºãã«ããã£ãŠã³ã³ããã¹ããç¶æããæ¹æ³ãæäŸãããŸãã
äžå¿çãªèãæ¹ã¯ãéåææäœãéå§ããããšãïŒäŸïŒHTTPãªã¯ãšã¹ãã®åä¿¡ïŒããã®æäœã«çµã³ã€ããã¹ãã¬ãŒãžã¹ããŒã¹ãåæåã§ãããšãããã®ã§ãããã®æäœã«ãã£ãŠçŽæ¥çãŸãã¯éæ¥çã«ããªã¬ãŒãããåŸç¶ã®éåæåŒã³åºãã¯ããã¹ãŠåãã¹ãã¬ãŒãžã¹ããŒã¹ã«ã¢ã¯ã»ã¹ã§ããŸããããã¯ãç¹å®ã®ãªã¯ãšã¹ãããã©ã³ã¶ã¯ã·ã§ã³ã«é¢é£ããç¶æ ãã¢ããªã±ãŒã·ã§ã³ã®ããŸããŸãªéšåãééããéã«ç¶æããããã«äžå¯æ¬ ã§ãã
ãªãAsync Local Storageã䜿çšããã®ãïŒ
ããã€ãã®äž»èŠãªå©ç¹ã«ãããALSã¯ãªã¯ãšã¹ãã³ã³ããã¹ã管çã«ãšã£ãŠé åçãªãœãªã¥ãŒã·ã§ã³ãšãªã£ãŠããŸãïŒ
- ã³ãŒãã®ç°¡çŽ åïŒ ãã¹ãŠã®é¢æ°ã«ã³ã³ããã¹ããªããžã§ã¯ããåŒæ°ãšããŠæž¡ãå¿ èŠããªããªããããã¯ãªãŒã³ã§èªã¿ãããã³ãŒãã«ãªããŸããããã¯ãäžè²«ããã³ã³ããã¹ãã®äŒæãç¶æããããšã倧ããªè² æ ã«ãªãåŸãå€§èŠæš¡ãªã³ãŒãããŒã¹ã§ã¯ç¹ã«äŸ¡å€ããããŸãã
- ä¿å®æ§ã®åäžïŒ 誀ã£ãŠã³ã³ããã¹ããçç¥ããããäžæ£ç¢ºã«æž¡ããããããªã¹ã¯ãæžãããããä¿å®æ§ãé«ãä¿¡é Œæ§ã®ããã¢ããªã±ãŒã·ã§ã³ã«ã€ãªãããŸããã³ã³ããã¹ã管çãALSå ã«éäžãããããšã§ãã³ã³ããã¹ããžã®å€æŽã管çãããããªãããšã©ãŒãçºçãã«ãããªããŸãã
- ãããã°ã®åŒ·åïŒ ç¹å®ã®ãªã¯ãšã¹ãã«é¢é£ããã³ã³ããã¹ããæ€æ»ããããã®äžå çãªå ŽæãæäŸããããšã§ããããã°ãç°¡çŽ åããŸããããŒã¿ã®æµããç°¡åã«è¿œè·¡ããã³ã³ããã¹ãã®äžæŽåã«é¢é£ããåé¡ãç¹å®ã§ããŸãã
- ããŒã¿äžè²«æ§ïŒ éåææäœå šäœãéããŠããŒã¿ãäžè²«ããŠå©çšå¯èœã§ããããšãä¿èšŒããç«¶åç¶æ ããã®ä»ã®ããŒã¿æŽåæ§ã®åé¡ã鲿¢ããŸããããã¯ãè€éãªãã©ã³ã¶ã¯ã·ã§ã³ãããŒã¿åŠçãã€ãã©ã€ã³ãå®è¡ããã¢ããªã±ãŒã·ã§ã³ã§ç¹ã«éèŠã§ãã
- ãã¬ãŒã¹ãšã¢ãã¿ãªã³ã°ïŒ ãªã¯ãšã¹ãåºæã®æ å ±ïŒäŸïŒãªã¯ãšã¹ãIDããŠãŒã¶ãŒIDïŒãALSå ã«ä¿åããããšã§ããªã¯ãšã¹ãã®ãã¬ãŒã¹ãšã¢ãã¿ãªã³ã°ã容æã«ããŸãããã®æ å ±ã¯ãã·ã¹ãã ã®è²ã ãªéšåãééãããªã¯ãšã¹ãã远跡ããããã«äœ¿çšã§ããããã©ãŒãã³ã¹ããšã©ãŒçã«é¢ãã貎éãªæŽå¯ãæäŸããŸãã
Async Local Storageã®ã³ã¢ã³ã³ã»ãã
ALSã广çã«äœ¿çšããããã«ã¯ã以äžã®ã³ã¢ã³ã³ã»ãããçè§£ããããšãäžå¯æ¬ ã§ãïŒ
- AsyncLocalStorage: ALSã€ã³ã¹ã¿ã³ã¹ãäœæããã³ç®¡çããããã®ã¡ã€ã³ã¯ã©ã¹ã§ããéåææäœã«åºæã®ã¹ãã¬ãŒãžã¹ããŒã¹ãæäŸããããã«
AsyncLocalStorageã®ã€ã³ã¹ã¿ã³ã¹ãäœæããŸãã - run(store, fn, ...args): æå®ããã
storeã®ã³ã³ããã¹ãå ã§ãæäŸããã颿°fnãå®è¡ããŸããstoreã¯ä»»æã®äŸ¡ã§ãããfnå ã§éå§ããããã¹ãŠã®éåææäœã§å©çšå¯èœã«ãªããŸããfnãšãã®éåæã®åã®å®è¡äžã«åŸç¶ã§getStore()ãåŒã³åºããšããã®storeã®å€ãè¿ãããŸãã - enterWith(store): ç¹å®ã®
storeã§æç€ºçã«ã³ã³ããã¹ãã«å ¥ããŸããããã¯`run`ã»ã©äžè¬çã§ã¯ãããŸããããç¹å®ã®ã·ããªãªãç¹ã«åææäœã«ãã£ãŠçŽæ¥ããªã¬ãŒãããªãéåæã³ãŒã«ããã¯ãæ±ãå Žåã«åœ¹ç«ã¡ãŸãã誀ã£ã䜿çšã¯ã³ã³ããã¹ãã®æŒæŽ©ã«ã€ãªããå¯èœæ§ãããããã䜿çšããéã«ã¯æ³šæãå¿ èŠã§ãã - exit(fn): çŸåšã®ã³ã³ããã¹ããçµäºããŸãã`enterWith`ãšçµã¿åãããŠäœ¿çšãããŸãã
- getStore(): ã¢ã¯ãã£ããªéåæã³ã³ããã¹ãã«é¢é£ä»ããããçŸåšã®ã¹ãã¢å€ãååŸããŸããã¢ã¯ãã£ããªã¹ãã¢ããªãå Žåã¯
undefinedãè¿ããŸãã - disable(): AsyncLocalStorageã€ã³ã¹ã¿ã³ã¹ãç¡å¹ã«ããŸããç¡å¹ã«ãªããšããã®åŸã®`run`ãŸãã¯`enterWith`ã®åŒã³åºãã¯ãšã©ãŒãã¹ããŒããŸããããã¯ããã¹ããã¯ãªãŒã³ã¢ããäžã«ãã䜿çšãããŸãã
Async Local Storageã®å®çšçãªäœ¿çšäŸ
ããŸããŸãªã·ããªãªã§ALSã䜿çšããæ¹æ³ã瀺ããããã€ãã®å®çšçãªäŸãèŠãŠãããŸãããã
äŸ1ïŒWebãµãŒããŒã§ã®ãªã¯ãšã¹ãIDã®è¿œè·¡
ãã®äŸã§ã¯ãALSã䜿çšããŠWebãªã¯ãšã¹ãå ã®ãã¹ãŠã®éåææäœã«ããã£ãŠäžæã®ãªã¯ãšã¹ãIDã远跡ããæ¹æ³ã瀺ããŸãã
const { AsyncLocalStorage } = require('async_hooks');
const express = require('express');
const uuid = require('uuid');
const asyncLocalStorage = new AsyncLocalStorage();
const app = express();
app.use((req, res, next) => {
const requestId = uuid.v4();
asyncLocalStorage.run(new Map(), () => {
asyncLocalStorage.getStore().set('requestId', requestId);
next();
});
});
app.get('/', (req, res) => {
const requestId = asyncLocalStorage.getStore().get('requestId');
console.log(`Handling request with ID: ${requestId}`);
res.send(`Request ID: ${requestId}`);
});
app.get('/another-route', async (req, res) => {
const requestId = asyncLocalStorage.getStore().get('requestId');
console.log(`Handling another route with ID: ${requestId}`);
// Simulate an asynchronous operation
await new Promise(resolve => setTimeout(resolve, 100));
const requestIdAfterAsync = asyncLocalStorage.getStore().get('requestId');
console.log(`Request ID after async operation: ${requestIdAfterAsync}`);
res.send(`Another route - Request ID: ${requestId}`);
});
app.listen(3000, () => {
console.log('Server listening on port 3000');
});
ãã®äŸã§ã¯ïŒ
AsyncLocalStorageã€ã³ã¹ã¿ã³ã¹ãäœæãããŸãã- ååä¿¡ãªã¯ãšã¹ãã«å¯ŸããŠäžæã®ãªã¯ãšã¹ãIDãçæããããã«ãããã«ãŠã§ã¢é¢æ°ã䜿çšãããŸãã
asyncLocalStorage.run()ã¡ãœããã¯ãæ°ããMapã®ã³ã³ããã¹ãå ã§ãªã¯ãšã¹ããã³ãã©ãå®è¡ãããªã¯ãšã¹ãIDãä¿åããŸãã- ãã®åŸããªã¯ãšã¹ãIDã¯ãéåææäœã®åŸã§ã
asyncLocalStorage.getStore().get('requestId')ãä»ããŠã«ãŒããã³ãã©å ã§ã¢ã¯ã»ã¹å¯èœã«ãªããŸãã
äŸ2ïŒãŠãŒã¶ãŒèªèšŒãšèªå¯
ALSã¯èªèšŒåŸã«ãŠãŒã¶ãŒæ å ±ãä¿åããããã«äœ¿çšã§ãããªã¯ãšã¹ãã®ã©ã€ããµã€ã¯ã«å šäœã§èªå¯ãã§ãã¯ã«å©çšã§ããããã«ããŸãã
const { AsyncLocalStorage } = require('async_hooks');
const express = require('express');
const asyncLocalStorage = new AsyncLocalStorage();
const app = express();
// Mock authentication middleware
const authenticateUser = (req, res, next) => {
// Simulate user authentication
const userId = 123; // Example user ID
const userRoles = ['admin', 'editor']; // Example user roles
asyncLocalStorage.run(new Map(), () => {
asyncLocalStorage.getStore().set('userId', userId);
asyncLocalStorage.getStore().set('userRoles', userRoles);
next();
});
};
// Mock authorization middleware
const authorizeUser = (requiredRole) => {
return (req, res, next) => {
const userRoles = asyncLocalStorage.getStore().get('userRoles') || [];
if (userRoles.includes(requiredRole)) {
next();
} else {
res.status(403).send('Unauthorized');
}
};
};
app.use(authenticateUser);
app.get('/admin', authorizeUser('admin'), (req, res) => {
const userId = asyncLocalStorage.getStore().get('userId');
res.send(`Admin page - User ID: ${userId}`);
});
app.get('/editor', authorizeUser('editor'), (req, res) => {
const userId = asyncLocalStorage.getStore().get('userId');
res.send(`Editor page - User ID: ${userId}`);
});
app.get('/public', (req, res) => {
const userId = asyncLocalStorage.getStore().get('userId');
res.send(`Public page - User ID: ${userId}`); // Still accessible
});
app.listen(3000, () => {
console.log('Server listening on port 3000');
});
ãã®äŸã§ã¯ïŒ
authenticateUserããã«ãŠã§ã¢ã¯ãŠãŒã¶ãŒèªèšŒãã·ãã¥ã¬ãŒããããŠãŒã¶ãŒIDãšããŒã«ãALSã«ä¿åããŸããauthorizeUserããã«ãŠã§ã¢ã¯ãALSãããŠãŒã¶ãŒããŒã«ãååŸããŠããŠãŒã¶ãŒãå¿ èŠãªããŒã«ãæã£ãŠãããã©ããã確èªããŸãã- ãŠãŒã¶ãŒIDã¯ãèªèšŒåŸããã¹ãŠã®ã«ãŒãã§ã¢ã¯ã»ã¹å¯èœã§ãã
äŸ3ïŒããŒã¿ããŒã¹ãã©ã³ã¶ã¯ã·ã§ã³ç®¡ç
ALSã¯ããŒã¿ããŒã¹ãã©ã³ã¶ã¯ã·ã§ã³ã管çããããã«äœ¿çšã§ãããªã¯ãšã¹ãå ã®ãã¹ãŠã®ããŒã¿ããŒã¹æäœãåããã©ã³ã¶ã¯ã·ã§ã³å ã§å®è¡ãããããšãä¿èšŒããŸãã
const { AsyncLocalStorage } = require('async_hooks');
const express = require('express');
const { Sequelize } = require('sequelize');
const asyncLocalStorage = new AsyncLocalStorage();
const app = express();
// Configure Sequelize
const sequelize = new Sequelize('database', 'user', 'password', {
dialect: 'sqlite',
storage: ':memory:', // Use in-memory database for example
logging: false,
});
// Define a model
const User = sequelize.define('User', {
username: Sequelize.STRING,
});
// Middleware to manage transactions
const transactionMiddleware = async (req, res, next) => {
const transaction = await sequelize.transaction();
asyncLocalStorage.run(new Map(), async () => {
asyncLocalStorage.getStore().set('transaction', transaction);
try {
await next();
await transaction.commit();
} catch (error) {
await transaction.rollback();
console.error('Transaction rolled back:', error);
res.status(500).send('Transaction failed');
}
});
};
app.use(transactionMiddleware);
app.post('/users', async (req, res) => {
const transaction = asyncLocalStorage.getStore().get('transaction');
try {
// Example: Create a user
const user = await User.create({
username: 'testuser',
}, { transaction });
res.status(201).send(`User created with ID: ${user.id}`);
} catch (error) {
console.error('Error creating user:', error);
throw error; // Propagate the error to trigger rollback
}
});
// Sync the database and start the server
sequelize.sync().then(() => {
app.listen(3000, () => {
console.log('Server listening on port 3000');
});
});
ãã®äŸã§ã¯ïŒ
transactionMiddlewareã¯Sequelizeãã©ã³ã¶ã¯ã·ã§ã³ãäœæãããããALSã«ä¿åããŸãã- ãªã¯ãšã¹ããã³ãã©å ã®ãã¹ãŠã®ããŒã¿ããŒã¹æäœã¯ãALSãããã©ã³ã¶ã¯ã·ã§ã³ãååŸããŠäœ¿çšããŸãã
- ãšã©ãŒãçºçããå Žåããã©ã³ã¶ã¯ã·ã§ã³ã¯ããŒã«ããã¯ãããããŒã¿ã®äžè²«æ§ãä¿èšŒãããŸãã
é«åºŠãªäœ¿çšæ³ãšèæ ®äºé
åºæ¬çãªäŸãè¶ ããŠãALSã䜿çšããéã«ã¯ããããã®é«åºŠãªäœ¿çšãã¿ãŒã³ãšéèŠãªèæ ®äºé ãæ€èšããŠãã ããïŒ
- ALSã€ã³ã¹ã¿ã³ã¹ã®ãã¹ãïŒ ALSã€ã³ã¹ã¿ã³ã¹ããã¹ãããŠéå±€çãªã³ã³ããã¹ããäœæã§ããŸãããã ããæœåšçãªè€éãã«æ³šæããã³ã³ããã¹ãã®å¢çãæç¢ºã«å®çŸ©ãããŠããããšã確èªããŠãã ããããã¹ããããALSã€ã³ã¹ã¿ã³ã¹ã䜿çšããå Žåã¯ãé©åãªãã¹ããäžå¯æ¬ ã§ãã
- ããã©ãŒãã³ã¹ãžã®åœ±é¿ïŒ ALSã¯å€§ããªå©ç¹ãæäŸããŸãããæœåšçãªããã©ãŒãã³ã¹ã®ãªãŒããŒãããã«æ³šæããããšãéèŠã§ããã¹ãã¬ãŒãžã¹ããŒã¹ã®äœæãšã¢ã¯ã»ã¹ã¯ãããã©ãŒãã³ã¹ã«ããããªåœ±é¿ãäžããå¯èœæ§ããããŸããã¢ããªã±ãŒã·ã§ã³ããããã¡ã€ãªã³ã°ããŠãALSãããã«ããã¯ã«ãªã£ãŠããªãããšã確èªããŠãã ããã
- ã³ã³ããã¹ãã®æŒæŽ©ïŒ ã³ã³ããã¹ãã®ç®¡çã誀ããšããããªã¯ãšã¹ãã®ããŒã¿ã誀ã£ãŠå¥ã®ãªã¯ãšã¹ãã«å
¬éãããã³ã³ããã¹ãæŒæŽ©ã«ã€ãªããå¯èœæ§ããããŸããããã¯ç¹ã«
enterWithãšexitã䜿çšããå Žåã«é¢é£ããŸããã³ã³ããã¹ãæŒæŽ©ãé²ãããã«ã¯ãæ éãªã³ãŒãã£ã³ã°ãã©ã¯ãã£ã¹ãšåŸ¹åºçãªãã¹ããäžå¯æ¬ ã§ããæœåšçãªåé¡ãæ€åºããããã«ããªã³ãã£ã³ã°ã«ãŒã«ãéçåæããŒã«ã®äœ¿çšãæ€èšããŠãã ããã - ãã®ã³ã°ããã³ã¢ãã¿ãªã³ã°ãšã®çµ±åïŒ ALSã¯ãã®ã³ã°ããã³ã¢ãã¿ãªã³ã°ã·ã¹ãã ãšã·ãŒã ã¬ã¹ã«çµ±åã§ããã¢ããªã±ãŒã·ã§ã³ã®åäœã«é¢ãã貎éãªæŽå¯ãæäŸããŸãããããã°ããã©ãã«ã·ã¥ãŒãã£ã³ã°ã容æã«ããããã«ããã°ã¡ãã»ãŒãžã«ãªã¯ãšã¹ãIDããã®ä»ã®é¢é£ããã³ã³ããã¹ãæ å ±ãå«ããŠãã ããããµãŒãã¹éã§ã³ã³ããã¹ããèªåçã«äŒæãããããã«ãOpenTelemetryã®ãããªããŒã«ã®äœ¿çšãæ€èšããŠãã ããã
- ALSã®ä»£æ¿ææ®µïŒ ALSã¯åŒ·åãªããŒã«ã§ããããã¹ãŠã®ã·ããªãªã§æåã®è§£æ±ºçãšã¯éããŸãããã¢ããªã±ãŒã·ã§ã³ã®ããŒãºã«ããé©ããŠããå Žåã¯ãã³ã³ããã¹ããªããžã§ã¯ããæç€ºçã«æž¡ããããäŸåæ§æ³šå ¥ã䜿çšããããããªã©ã代æ¿ã¢ãããŒããæ€èšããŠãã ãããã³ã³ããã¹ãç®¡çæŠç¥ãéžæããéã«ã¯ãè€éããããã©ãŒãã³ã¹ãä¿å®æ§ã®éã®ãã¬ãŒããªããè©äŸ¡ããŠãã ããã
ã°ããŒãã«ãªèŠç¹ãšåœéçãªèæ ®äºé
ã°ããŒãã«ãªãŠãŒã¶ãŒåãã«ã¢ããªã±ãŒã·ã§ã³ãéçºããå ŽåãALSã䜿çšããéã«ã¯ä»¥äžã®åœéçãªåŽé¢ãèæ ®ããããšãéèŠã§ãïŒ
- ã¿ã€ã ãŸãŒã³ïŒ ç°ãªãã¿ã€ã ãŸãŒã³ã®ãŠãŒã¶ãŒã«æ¥ä»ãšæå»ãæ£ãã衚瀺ãããããã«ãã¿ã€ã ãŸãŒã³æ å ±ãALSã«ä¿åããŸããã¿ã€ã ãŸãŒã³å€æãåŠçããã«ã¯ãMoment.jsãLuxonãªã©ã®ã©ã€ãã©ãªã䜿çšããŸããäŸãã°ããŠãŒã¶ãŒããã°ã€ã³ããåŸã«ã奜ã¿ã®ã¿ã€ã ãŸãŒã³ãALSã«ä¿åããããšãèããããŸãã
- ããŒã«ãªãŒãŒã·ã§ã³ïŒ ã¢ããªã±ãŒã·ã§ã³ãæ£ããèšèªã§è¡šç€ºãããããã«ããŠãŒã¶ãŒã®å¥œã¿ã®èšèªãšãã±ãŒã«ãALSã«ä¿åããŸãã翻蚳ã管çããã«ã¯ãi18nextãªã©ã®ããŒã«ãªãŒãŒã·ã§ã³ã©ã€ãã©ãªã䜿çšããŸãããŠãŒã¶ãŒã®ãã±ãŒã«ã¯ãæåçå奜ã«å¿ããŠæ°å€ãæ¥ä»ãé貚ããã©ãŒãããããããã«äœ¿çšã§ããŸãã
- éè²šïŒ äŸ¡æ Œãæ£ãã衚瀺ãããããã«ããŠãŒã¶ãŒã®å¥œã¿ã®é貚ãALSã«ä¿åããŸããéè²šå€æãåŠçããã«ã¯ãéè²šå€æã©ã€ãã©ãªã䜿çšããŸãããŠãŒã¶ãŒã®çŸå°é貚ã§äŸ¡æ Œã衚瀺ããããšã§ããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãåäžããã³ã³ããŒãžã§ã³çãåäžããå¯èœæ§ããããŸãã
- ããŒã¿ãã©ã€ãã·ãŒèŠå¶ïŒ ãŠãŒã¶ãŒããŒã¿ãALSã«ä¿åããéã¯ãGDPRãªã©ã®ããŒã¿ãã©ã€ãã·ãŒèŠå¶ã«æ³šæããŠãã ãããã¢ããªã±ãŒã·ã§ã³ã®éçšã«å¿ èŠãªããŒã¿ã®ã¿ãä¿åããããŒã¿ãå®å šã«åãæ±ã£ãŠããããšã確èªããŠãã ãããäžæ£ã¢ã¯ã»ã¹ãããŠãŒã¶ãŒããŒã¿ãä¿è·ããããã«ãé©åãªã»ãã¥ãªãã£å¯Ÿçãè¬ããŠãã ããã
çµè«
JavaScriptã®Async Local Storageã¯ãéåæJavaScriptã¢ããªã±ãŒã·ã§ã³ã§ãªã¯ãšã¹ãã³ã³ããã¹ãã管çããããã®å ç¢ã§ãšã¬ã¬ã³ããªãœãªã¥ãŒã·ã§ã³ãæäŸããŸããã³ã³ããã¹ãåºæã®ããŒã¿ãALSå ã«ä¿åããããšã§ãã³ãŒããç°¡çŽ åããä¿å®æ§ãåäžããããããã°èœåãé«ããããšãã§ããŸãããã®ã¬ã€ãã§æŠèª¬ããã³ã¢ã³ã³ã»ãããšãã¹ããã©ã¯ãã£ã¹ãçè§£ããããšã§ãçŸä»£ã®éåæããã°ã©ãã³ã°ã®è€éãã«å¯Ÿå¿ã§ãããã¹ã±ãŒã©ãã«ã§ä¿¡é Œæ§ã®é«ãã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã«ALSã广çã«æŽ»çšããåãåŸãããŸããã¢ããªã±ãŒã·ã§ã³ã®æé©ãªããã©ãŒãã³ã¹ãšã»ãã¥ãªãã£ã確ä¿ããããã«ãããã©ãŒãã³ã¹ãžã®åœ±é¿ãšæœåšçãªã³ã³ããã¹ãæŒæŽ©ã®åé¡ãåžžã«èæ ®ããããšãå¿ããªãã§ãã ãããALSãæ¡çšããããšã§ãéåæã¯ãŒã¯ãããŒã®ç®¡çã«ãããæ°ããªã¬ãã«ã®æç¢ºããšå¶åŸ¡ãè§£æŸãããæçµçã«ããå¹ççã§ä¿å®æ§ã®é«ãã³ãŒãã«ã€ãªãããŸãã