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

jquery - How do I wait for a javascript function to return a response using Chrome.storage API? - Stack Overflow

programmeradmin6浏览0评论

I am trying to use the following code to set and get name value pairs in a Chrome Extension.

if (!this.Chrome_getValue || (this.Chrome_getValue.toString && this.Chrome_getValue.toString().indexOf("not supported") > -1)) {
    this.Chrome_getValue = function (key, def) {
        chrome.storage.local.get(key, function (result) {
            return result[key];
        });
    };
    this.Chrome_setValue = function (key, value) {
        var obj = {};
        obj[key] = value;
        return chrome.storage.local.set(obj)
    }
}

I am then invoking these as follows:

Chrome_setValue("City", "London");

var keyValue = Chrome_getValue("City");

The problem is the keyValue is always 'undefined' even if I put a 1 second delay in trying to read back the value. I understand this is because the 'chrome.storage.local.get' function is asynchronous.. the following code works fine.

Chrome_setValue("City", "London");

chrome.storage.local.get("City", function (result) {
     alert(result["City"]);
});

Is there any way when binding the keyValue (using get) I can force the code to wait for the function to return a response? Or perhaps I'm approaching this from the wrong angle. Essentially I am looking for a way I can abstract out the set and get methods for handling data within the chrome.storage framework? Ideally two simple functions I can call for setting and retrieving name value pairs.

Before I was using localStorage which was very straightforward.

//Set
localStorage["City"] = "London";

//Get
var keyValue = localStorage["City"];

I am trying to use the following code to set and get name value pairs in a Chrome Extension.

if (!this.Chrome_getValue || (this.Chrome_getValue.toString && this.Chrome_getValue.toString().indexOf("not supported") > -1)) {
    this.Chrome_getValue = function (key, def) {
        chrome.storage.local.get(key, function (result) {
            return result[key];
        });
    };
    this.Chrome_setValue = function (key, value) {
        var obj = {};
        obj[key] = value;
        return chrome.storage.local.set(obj)
    }
}

I am then invoking these as follows:

Chrome_setValue("City", "London");

var keyValue = Chrome_getValue("City");

The problem is the keyValue is always 'undefined' even if I put a 1 second delay in trying to read back the value. I understand this is because the 'chrome.storage.local.get' function is asynchronous.. the following code works fine.

Chrome_setValue("City", "London");

chrome.storage.local.get("City", function (result) {
     alert(result["City"]);
});

Is there any way when binding the keyValue (using get) I can force the code to wait for the function to return a response? Or perhaps I'm approaching this from the wrong angle. Essentially I am looking for a way I can abstract out the set and get methods for handling data within the chrome.storage framework? Ideally two simple functions I can call for setting and retrieving name value pairs.

Before I was using localStorage which was very straightforward.

//Set
localStorage["City"] = "London";

//Get
var keyValue = localStorage["City"];
Share Improve this question asked May 1, 2013 at 10:50 QFDevQFDev 9,00815 gold badges64 silver badges85 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

QF_D, I'm into educated guesswork here, so be prepared for this not to work first time .....

..... here goes :

if (!this.Chrome_getValue || (this.Chrome_getValue.toString && this.Chrome_getValue.toString().indexOf("not supported") > -1)) {
    this.Chrome_getValue = function (key, def) {
        var dfrd = $.Deferred();
        chrome.storage.local.get(key, function (result) {
            dfrd.resolve(result[key]);
        });
        return dfrd.promise();
    };
    this.Chrome_setValue = function (key, value) {
        var dfrd = $.Deferred();
        var obj = {};
        obj[key] = value;
        var listen = function(changes, namespace) {
            dfrd.resolve(changes[key]);
            chrome.storage.onChanged.removeListener(listen);//remove, to prevent accumulation of listeners
        }
        chrome.storage.onChanged.addListener(listen);
        chrome.storage.local.set(obj);
        return dfrd.promise()
    }
}

The get and set functions should thus return jQuery promises. The promise returned by the set function is resolved with a StorageChange object defined here. In general you won't need this object, rather just respond to the promise being resolved.

Everything above is untested. I'm not too sure about :

  • chrome.storage.onChanged..... Should it be chrome.storage.local.onChanged....?
  • .removeListener(). It seems resonable that it should exist if addListener exists, though I can't find any evidence of it.

Well, it's essentially because the chrome.storage API is asynchronous. You are facing something which is at the core of JavaScript.

What's executed in the chrome.storage.get callback is not returned by chrome.storage.get. You have 2 ways of dealing with it:

  • deal with the storage value in the callback
  • use the Promise pattern to keep your code feeling synchronous (cf. the previous answer)

You really have to figure out the difference between synchronous and asynchronous.

发布评论

评论列表(0)

  1. 暂无评论