Is HTML5 localStorage asynchronous?
Nope, all localStorage
calls are synchronous.
Is any solution to do localstorage setItem in asynchronous way in javascript
localStorage
is a synchronous API. You could defer the setItem
method execution with the Promise
object, giving them an asynchronous behaviour:
const asyncLocalStorage = {
setItem: function (key, value) {
return Promise.resolve().then(function () {
localStorage.setItem(key, value);
});
},
getItem: function (key) {
return Promise.resolve().then(function () {
return localStorage.getItem(key);
});
}
};
// Demo
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'));
See it run on repl.it, as SO snippets do not allow the use of localStorage
.
With the newer async
/await
syntax, this asyncLocalStorage
can be written as:
const asyncLocalStorage = {
setItem: async function (key, value) {
await null;
return localStorage.setItem(key, value);
},
getItem: async function (key) {
await null;
return localStorage.getItem(key);
}
};
repl.it
Note about "asynchronous"
Be aware that, although the above let's you continue with other code immediately, once that code has been executed, the job of accessing local storage will kick in and will use the same thread. So it is not like it runs in the background, in parallel with your own JS code. It just delays the job until after the call stack is empty. It also does not process other events from the browser context until it also finishes that job. So, for instance, it will still block the GUI.
If you need the access to happen in parallel, then you're out of luck with localStorage
. For instance, that API is not available in Web Workers, which would otherwise have been a possible way out.
You could look into the IndexedDB API
as an alternative. But:
- It is much more complicated to work with
- Although it has an asynchronous interface, several browser implementations still block the DOM (so the above comments apply)
- IndexedDB can be used by a Web Worker, which gives better parallelism, but makes it even more complex to implement.
how to wait until localStorage.setItem finishes in angular 4
In case anyone is getting the same kind of a issue... the reason for this was I have created a variable in my service class to save the current user and set the value for that variable inside the constructor. So, in the login page when the authenticate
method gets called it tries to initialize the variable but since user is not logged in yet it is still null
. That was causing the issue.
Error when retrieving from localStorage async using promises
I made a codesandbox of your code refactored.
Code on Codesandbox
The code looks like this:
Note: The code won't run properly on Stackoverflow, since you are making a request and using localstorage.
function getData() {
console.log("running");
// check fir requestAll in local storage. null if it doesn't exist.
const cache = localStorage.getItem("requestAll");
// if the data is in the cache, return it.
if (cache) return Promise.resolve(JSON.parse(cache));
// else get the data and store it.
return Promise.resolve(
fetch("https://data.cityofchicago.org/resource/xzkq-xp2w.json")
.then((res) => res.json())
.then((data) => {
localStorage.setItem("requestAll", JSON.stringify(data));
return data;
})
);
}
(() => {
getData().then(console.log);
})();
How is indexedDB conceptually different from HTML5 local storage?
IndexedDB is not a key-value store in the same way that Local Storage is. Local storage just stores strings, so to put an object in local storage the usual approach is to JSON.stringify it:
myObject = {a: 1, b: 2, c: 3};
localStorage.setItem("uniq", JSON.stringify(myObject));
This is fine for finding the object with key uniq
, but the only way to get the properties of myObject back out of local storage is to JSON.parse the object and examine it:
var myStorageObject = JSON.parse(localStorage.getItem("uniq"));
window.alert(myStorageObject.b);
This is fine if you only have one, or a few objects, in local storage. But imagine you have a thousand objects, all of which have a property b
, and you want to do something just with those ones where b==2
. With local storage you'll have to loop through the entire store and check b
on each item, which is a lot of wasted processing.
With IndexedDB you can store stuff other than strings in the value: "This includes simple types such as DOMString and Date as well as Object and Array instances." Not only that, but you can create indexes on properties of the objects that you stored in the value. So with IndexedDb you can put those same thousand objects in it but create an index on the b
property and use that to just retrieve the objects where b==2
without the overhead of scanning every object in the store.
At least that's the idea. The IndexedDB API isn't very intuitive.
They appear to run in the same thread as the async calls were made. How will this not block the UI?
Asynchronous is not the same thing as multi-threaded, JavaScript, as a rule, is not multi-threaded. Any heavy processing you do in JS will block the UI, if you want to minimize blocking the UI try Web Workers.
indexedDB allows a larger store. Why not increase the size of the HTML5 store?
Because, without proper indexing, it would get increasingly slower the larger it got.
Converting Localstorage to AsyncStorage in React Native
You need to wait for AsyncStorage to get your item data:
useEffect(()=>{
const fn = async () => {
const value = await AsyncStorage.getItem(`myData${id}`);
if(value){
setData(JSON.parse(value));
}
}
fn();
},[]);
or
useEffect(()=>{
AsyncStorage
.getItem(`myData${id}`)
.then( value => {
if(value){
setData(JSON.parse(value));
}
});
},[]);
javascript chrome localStorage async using promises
was a problem with my set function, fixed wih this:
function setVarInLocalStorage(name, value){ return new Promise(function(resolve, reject) { //console.log("set: setting "+ name +" in localstorage to " + value)
var name = 'k1'; var obj= {}; obj[name] = value;
chrome.storage.sync.set(obj, function(){ //console.log("set: localStorage[name] = " + localStorage[name]) resolve("var set successfully") }); })}
Related Topics
How to Pre-Populate the Sms Body Text Via an HTML Link
Wcf Service to Accept a Post Encoded Multipart/Form-Data
Make an Image Responsive - the Simplest Way
Is Type="Text/Css" Necessary in a ≪Link≫ Tag
How to Post/Submit an Input Checkbox That Is Disabled
Dynamically Adding and Removing Components in Angular
Align Labels in Form Next to Input
Link a .CSS File in Another Folder
Html Inside Twitter Bootstrap Popover
Unwanted Margin in Inline-Block List Items
Making the Main Scrollbar Always Visible
Difference Between ≪Input Type='Submit' /≫ and ≪Button Type='Submit'≫Text≪/Button≫
Css3 Border-Radius Clipping Issues
How to Put Text Over Images in HTML
What Is the Use of Style="Clear:Both"
Should Global CSS Styles Be Set on the HTML Element or the Body Element