2013-05-01 103 views
9

我正嘗試使用以下代碼在Chrome擴展程序中設置並獲取名稱值對。如何等待JavaScript函數使用Chrome.storage API返回響應?

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) 
    } 
} 

我然後調用這些如下:

Chrome_setValue("City", "London"); 

var keyValue = Chrome_getValue("City"); 

問題是的keyValue總是「未定義」即使我放了1秒的延遲,試圖回讀值。我明白這是因爲'chrome.storage.local.get'函數是異步的..下面的代碼工作正常。

Chrome_setValue("City", "London"); 

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

是否有任何約束力的keyValue(使用get),我可以強制代碼等待函數返回的響應時的方式?或者我可能從錯誤的角度來解決這個問題。本質上,我正在尋找一種方法來抽象出在chrome.storage框架內處理數據的setget方法?理想情況下,我可以調用兩個簡單函數來設置和檢索名稱值對。

在我使用localStorage之前,這非常簡單。

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

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

回答

4

QF_D,我到教育的猜測在這裏,所以要爲此做好了準備沒有工作第一次.....

.....這裏有雲:

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() 
    } 
} 

get和set函數應該返回jQuery promise。由設置函數返回的諾言通過StorageChange定義的對象here解決。一般而言,您不需要這個對象,而只是迴應正在解決的承諾。

以上所有內容均未經過測試。我不太確定:

  • chrome.storage.onChanged....。應該是chrome.storage.local.onChanged....
  • .removeListener()。似乎合理的是,如果存在addListener,它應該存在,但我找不到任何證據。
+0

謝謝甜菜根,這是非常有建設性的!發佈後,我開始懷疑我是否過度思考這個問題。實際上,我需要我的Chrome擴展程序將數據從subdomain1.website.com持久保存到subdomain2.website.com,localStorage不會執行某些操作。許多解決方案都提到使用background.js,所以我現在正在探索這條道路。 – QFDev 2013-05-01 12:36:53

+0

順便說一句,Chrome中用於存儲變量的任何方法都依賴於異步函數!所以沒有放棄使用上面描述的$ .Deferred()方法。我遇到的問題是搞清楚如何處理返回的dfrd.promise()對象...我如何從中找到值? – QFDev 2013-05-01 13:41:57

+0

[This](http://api.jquery.com/category/deferred-object/)可能是瞭解Deferreds和Promises的最佳起點。要處理一個Deferred(以及由此派生的Promise派生)的值,需要創建處理程序(函數)作爲'.then()'或'.done()'方法的參數。 – 2013-05-01 17:01:51

3

嗯,這基本上是因爲chrome.storage API是異步。您正面臨着JavaScript的核心問題。

執行什麼chrome.storage.get回調不返回通過chrome.storage.get。你有2種方式處理這個問題的:

  • 應對回調
  • 存儲值使用無極模式,讓您的代碼感覺同步(參見前面的答案)

你真的必須弄清楚同步異步之間的區別。