9

Sto cercando di utilizzare il seguente codice per impostare e ottenere coppie di valori nome in un'estensione di Chrome.Come posso aspettare che una funzione javascript restituisca una risposta utilizzando l'API Chrome.storage?

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

sto invocando poi questi come segue:

Chrome_setValue("City", "London"); 

var keyValue = Chrome_getValue("City"); 

Il problema è la keyValue è sempre 'indefinito', anche se ho messo un ritardo di 1 secondo nel tentativo di leggere nuovamente il valore. Capisco questo perché la funzione 'chrome.storage.local.get' è asincrona .. il seguente codice funziona bene.

Chrome_setValue("City", "London"); 

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

C'è un modo in cui il legame keyValue (utilizzando get) posso forzare il codice di aspettare la funzione per restituire una risposta? O forse mi sto avvicinando da un angolo sbagliato. In sostanza sto cercando un modo per estrapolare i metodi set e get per la gestione dei dati all'interno del framework chrome.storage? Idealmente due semplici funzioni che posso chiamare per impostare e recuperare coppie di valori nominali.

Prima di utilizzare localStorage era molto semplice.

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

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

risposta

4

QF_D, io sono in congetture educato qui, quindi preparatevi per questo non lavorare prima volta .....

..... ecco qui:

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

Le funzioni get e set dovrebbero quindi restituire le promesse di jQuery. La promessa restituita dalla funzione impostata viene risolta con un oggetto StorageChange definito here. In generale non avrai bisogno di questo oggetto, piuttosto risponderai solo alla promessa che verrà risolta.

Tutto sopra non è testato. Non sono troppo sicuro:

  • chrome.storage.onChanged..... Dovrebbe essere chrome.storage.local.onChanged....?
  • .removeListener(). Sembra ragionevole che debba esistere se esiste addListener, anche se non riesco a trovarlo.
+0

Grazie a Beetroot, è molto costruttivo! Dopo aver postato questo, tuttavia, ho iniziato a chiedermi se pensavo troppo a questo problema. In effetti ho bisogno che la mia estensione per Chrome mantenga i dati da subdomain1.website.com a subdomain2.website.com, qualcosa che localStorage non fa. Molte soluzioni menzionano l'uso di background.js quindi sto esplorando questa strada. – QFDev

+0

Incidentalmente qualsiasi metodo in Chrome per la memorizzazione delle variabili si basa su una funzione asincrona! Quindi non c'è modo di evitare l'uso del metodo $ .Deferred() che descrivi sopra. Il problema che sto avendo è capire cosa fare con l'oggetto dfrd.promise() restituito ... Come posso trovare il valore da questo? – QFDev

+0

[Questo] (http://api.jquery.com/category/deferred-object/) è probabilmente il miglior punto di partenza per conoscere Deferreds and Promises. Per lavorare con un valore con cui viene rimossa una Deferred (e quindi una Promessa derivata da essa), create i gestori (funzioni) come parametri per i metodi '.then()' o '.done()'. –

3

Ebbene, è essenzialmente perché l'API chrome.storage è asincrono. Stai affrontando qualcosa che è al centro di JavaScript.

Cosa viene eseguito nella callback chrome.storage.getnon viene restituito entro il chrome.storage.get. Hai 2 modi di trattare con esso:

  • accordo con il valore di memorizzazione nella richiamata
  • utilizzare il modello di promessa di mantenere il vostro codice di sensazione sincrona (cfr risposta precedente)

Devi davvero capire la differenza tra sincrono e asincrono.

Problemi correlati