我正在构建Chrome扩展程序并编写了此代码。
var Options = function(){};
Options.prototype = {
getMode: function(){
return chrome.storage.sync.get("value", function(e){
console.log(e); // it prints 'Object {value: "test"}'.
return e;
});
},
setMode: function(){
chrome.storage.sync.set({"value": "test"}, function(e) {
})
}
}
var options = new Options();
options.setMode();
console.log(options.getMode()); // it prints 'undefined'.
我希望它能打印
Object {value: "set up"}
当我致电options.getMode()
时,会打印undefined
。
有谁知道如何解决这个问题?
答案 0 :(得分:18)
chrome.storage
API是asynchronous - 它不会直接返回它,而是将其作为参数传递给回调函数。函数调用本身总是返回undefined
。
这通常用于允许其他方法运行而不必等到某些响应或完成 - 例如setTimeout
(唯一的区别是它返回一个计时器值,而不是undefined
)。
例如,拿这个:
setTimeout(function () { alert(1); }, 10000);
alert(0);
因为setTimeout
是异步的,所以在整个函数完成之前它不会停止所有代码,而是最初返回,仅在稍后完成时调用函数 - 这就是为什么0在1之前出现。
出于这个原因,你不能简单地执行以下操作:
// "foo" will always be undefined
var foo = asyncBar(function (e) { return e; });
通常,您应该在回调中放置您想要做的事情(异步函数完成时调用的函数)。这是编写异步代码的一种相当常见的方法:
function getValue(callback) {
chrome.storage.sync.get("value", callback);
}
您可以将整个部分代码放在回调中 - 没有什么可以阻止您这样做。所以不要做以下事情:
console.log(getValue()); // typical synchronous method of doing something
这可能是一个更好的主意:
// how it would be done in asynchronous code
getValue(function (value) {
console.log(value);
});
答案 1 :(得分:2)
chrome.storage.sync.get
是异步调用的,这就是为什么你必须传递一个回调,以便将来执行它。
当您尝试打印返回的getMode
值时,您将在排队要执行的异步调用后打印任何chrome.storage.sync.get
返回的返回值。
这是人们在javascript中常犯的错误,而他们正在学习使用异步调用。
答案 2 :(得分:1)
Chrome storage API是异步的,它使用callback
,这就是为什么您会遇到这种情况。
您可以使用Promise
API来解决此异步问题,该问题更简单,更简洁。这是一个示例:
async function getLocalStorageValue(key) {
return new Promise((resolve, reject) => {
try {
chrome.storage.sync.get(key, function (value) {
resolve(value);
})
}
catch (ex) {
reject(ex);
}
});
}
const result = await getLocalStorageValue("my-key");