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);
我正在尝试升级我的Chrome扩展程序以适应清单版本2 当我运行上面的代码时,我得到第一个console.log返回“new”,第二个返回“old”。如果我想将css设置为新值,我怎么能得到两个“新”?
答案 0 :(得分:5)
我将解释为什么你会得到这种行为以及如何解决。
这是你的代码:
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 / O的javascript API(至少来自浏览器)是异步的,这包括chrome.storage API,因为它访问数据库/文件系统或暗示I / O的东西操作
其次,Javascript代码结合了同步和异步代码运行,因此混淆
异步代码在JS EventLoop上运行,总是在同步代码之后(JS上没有线程),因此,在代码中,5总是会在之前运行 :
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
事实上,有可能在>>之前运行,在之后运行(取决于I / O操作完成的速度并调用您的回调)
现在,解决方案
你需要在回调中做任何你想要检索的信息,你可以喜欢或不喜欢这种编程风格,但它是JS方式(一旦代码变得更复杂并消耗更多我/ O api你会担心回调地狱,它可以使用Promises / Deferred解决,但这是另一回事)
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