使用chrome.storage.sync.get返回undefined返回值

时间:2013-09-09 13:14:13

标签: javascript google-chrome-extension

我正在构建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

有谁知道如何解决这个问题?

3 个答案:

答案 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");