localStorage
operates synchronously. To introduce an asynchronous behavior, you can utilize the Promise
object to defer the execution of the setItem
method:
const asyncLocalStorage = {
setItem(key, value) {
return Promise.resolve().then(function () {
localStorage.setItem(key, value);
});
},
getItem(key) {
return Promise.resolve().then(function () {
return localStorage.getItem(key);
});
}
};
// Example
const data = Date.now() % 1000;
asyncLocalStorage.setItem('mykey', data).then(function () {
return asyncLocalStorage.getItem('mykey');
}).then(function (value) {
console.log('Value has been set to:', value);
});
console.log('waiting for value to become ' + data +
'. Current value: ', localStorage.getItem('mykey'));
(You can also use queueMicrotask instead of Promise.resolve().then
. It achieves the same outcome without creating or returning a promise, so you cannot chain a then
call).
With the newer async
/await
syntax, the asyncLocalStorage
can be defined as:
const asyncLocalStorage = {
async setItem(key, value) {
await null;
return localStorage.setItem(key, value);
},
async getItem(key) {
await null;
return localStorage.getItem(key);
}
};
Note about "asynchronous"
It's important to note that while the above approach allows you to proceed with other code immediately, the local storage access will still occur on the same thread after the call stack is empty. This means it doesn't run in the background in parallel with your JavaScript code, but simply delays the task. Keep in mind that it may still block the GUI as it processes the job.
If you require parallel access, consider alternatives like the IndexedDB API
:
- It is more complex to work with compared to
localStorage
- Some browser implementations may still block the DOM despite its asynchronous interface
- IndexedDB can be utilized in Web Workers for better parallelism, though implementation becomes even more intricate