最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How chrome.storage.local.get sets a value? - Stack Overflow

programmeradmin2浏览0评论
var storage = chrome.storage.local;
var css = "old";
storage.set({'css': 'new'});
storage.get('css', function(items) {
    if (items.css) {
        css = items.css;
        console.log(css);
    }
});
console.log(css);

I am trying to upgrade my chrome extension to fit the manifest version 2.
While I run the code above, I get the first console.log returns "new" and the second one returns "old". How can I get two "new" if I want to set css to a new value?

var storage = chrome.storage.local;
var css = "old";
storage.set({'css': 'new'});
storage.get('css', function(items) {
    if (items.css) {
        css = items.css;
        console.log(css);
    }
});
console.log(css);

I am trying to upgrade my chrome extension to fit the manifest version 2.
While I run the code above, I get the first console.log returns "new" and the second one returns "old". How can I get two "new" if I want to set css to a new value?

Share Improve this question asked Sep 3, 2012 at 18:55 user1597243user1597243 952 silver badges7 bronze badges 3
  • 10 Like most Chrome APIs, chrome.storage.get/set are asynchronous. I've written an explanation of this in easy terms, which can be found here. – Rob W Commented Sep 3, 2012 at 21:11
  • Thank you for that answer. That's a very good explanation . However, I really want to ues 'css' outside the callback function. Is there any way to to so? – user1597243 Commented Sep 4, 2012 at 14:23
  • No. You cannot turn an asynchronous function in a synchronous function without changing the flow of your application. – Rob W Commented Sep 4, 2012 at 17:59
Add a ment  | 

1 Answer 1

Reset to default 5

I will explain why you are getting that behavior and how to fix.

This is your code:

var storage = chrome.storage.local;
var css = "old";
storage.set({'css': 'new'});
storage.get('css', function(items) {
  if (items.css) {
    css = items.css;
    console.log(css);
  }
});
console.log(css);

First of all you should know that by design, most of javascript API (at least from browser) accesing I/O is asynchronic , this include the chrome.storage API because it access a DB/filesystem or something implying I/O operations

Second, the Javascript code bine both, synchronous and asynchronous code running, hence the confusion

Asynchronous code runs on JS EventLoop , always after your synchronous code (there is no threads on JS), so, in your code, 5 always will run before 6:

var storage = chrome.storage.local; // 1
var css = "old"; // 2
storage.set({'css': 'new'}); // 3
storage.get('css', function(items) {
  // 6. this only will run AFTER this synchronous code returns
  if (items.css) {
    css = items.css;
    console.log(css);
  }
}); // 4
console.log(css); // 5. this always run before ANY callback

In fact there is chance of things running before 6 and after 5 (depending on how fast the I/O operation pletes and invoke your callback)

Now, the solution

You need to do in the callback whatever you want to do with the retrieved info, this style of programming you can like it or not, but it is the JS way (soon as the code turns more plex and consume more I/O api you will be worried about callback hells and it can be addressed using Promises/Deferred, but that's another matter)

var storage = chrome.storage.local; // 1
// var css = "old"; // 2
storage.set({'css': 'new'}); // 3
storage.get('css', function(items) {
  // 5. this only will run AFTER this synchronous code returns
  if (items.css) {
    var css = items.css; // this variable belongs to this scope
    // do here whatever you need with the retrieved info
    // since it is CSS, maybe you want to create a new stylesheet of that (is only an example)
    var style = document.createElement("style");
    style.innerText = css;
    document.head.appendChild(style);
  }
}); // 4
// console.log(css); // can't access css here, is synchronous and it runs before the callback
发布评论

评论列表(0)

  1. 暂无评论