简体   繁体   中英

Chrome Extension | Is there any way to make chrome.storage.local.get() return something?

in my chrome extension I need to use chrome storage. In my background script first I create an object and add it to chrome storage and then I want to get my object from there and to be returned. Something like that:

...
var obj = {};
chrome.storage.local.set(obj, function () { });
...
var data = getData(obj); // I want my object to be returned here

var returnedData = null;
function getData(obj) {
    chrome.storage.local.get(obj, function(result) {
        returnedData = result; // here it works, I can do something with my object
    });
    return returnedData; // here it doesn't work
} 

As far as I understood from here chrome.storage.local.get is asynchronous with its consequences. But is there any way how to get something from chrome storage and make it to be returned? I mean maybe I should wrap chrome.storage.local.get in another function or so?

Many thanks in advance!

If you want to stay away from global variables and you're okay with modern browser requirements, then you can implement a native JavaScript Promise object . For example, here's a function that returns the stored data for a single given key:

function getData(sKey) {
  return new Promise(function(resolve, reject) {
    chrome.storage.local.get(sKey, function(items) {
      if (chrome.runtime.lastError) {
        console.error(chrome.runtime.lastError.message);
        reject(chrome.runtime.lastError.message);
      } else {
        resolve(items[sKey]);
      }
    });
  });
}

// Sample usage given this data:
// { foo: 'bar' }
getData('foo').then(function(item) {
  // Returns "bar"
  console.log(item);
});

If you need support for IE11 and below, then you'll have to turn to a library like jQuery .

No it's not possible

But there are several ways around this problem

  1. Do everything you want to do with the data returned from .get() inside the callback (or start it from there using function calls). This is what @wernersbacher posted
  2. Take a look at deferreds (jQuery or Q libraries). A deferred's promise can be returned from getData. Inside the .get() callback, you can resolve the deferred. Outside of getData you can use .then() to do something after the deferred resolved

Something like this

function getData(obj) {
    var deferred = $.Deferred();
    chrome.storage.local.get(obj, function(result) {
       deferred.resolve(result);
    });
    return deferred.promise();
}

$.when(getData(obj)).then(function(data) {
   // data has value of result now
};

You have to do it like that:

var returnedData = null;
function setData(value) {
 returnedData = value;
}
function getData(obj) {
    chrome.storage.local.get(obj, function(result) {
        setData(result); // here it works, I can do something with my object
    });
    return; // here it doesn't work
} 

..because you tried to return a value which did not get read from storage yet, so it's null.

You need to handle it with callback functions. Here are two examples. You use a single function to set, however you create a separate function for each "On Complete". You could easily modify your callback to pass additional params all the way through to perform your needed task.

function setLocalStorage(key, val) {
    var obj = {};
    obj[key] = val;
    chrome.storage.local.set(obj, function() {
        console.log('Set: '+key+'='+obj[key]);
    });
}

function getLocalStorage(key, callback) {
    chrome.storage.local.get(key, function(items) {
        callback(key, items[key]);
    });
}

setLocalStorage('myFirstKeyName', 'My Keys Value Is FIRST!');
setLocalStorage('mySecondKeyName', 'My Keys Value Is SECOND!');

getLocalStorage('myFirstKeyName', CallbackA);
getLocalStorage('mySecondKeyName', CallbackB);


// Here are a couple example callback 
// functions that get executed on the 
// key/val being retrieved. 

function CallbackA(key, val) {
    console.log('Fired In CallbackA: '+key+'='+val);
}

function CallbackB(key, val) {
    console.log('Fired In CallbackA: '+key+'='+val);
}

Update with Manifest V3:

Now chrome.storage.local.get() function returns a promise that you can chain or can await in an async function.

const storageCache = { count: 0 };
// Asynchronously retrieve data from storage.local, then cache it.
const initStorageCache = chrome.storage.local.get().then((items) => {
  // Copy the data retrieved from storage into storageCache.
  Object.assign(storageCache, items);
});

Note: You must omit the callback paramter to get the promise.

Reference: https://developer.chrome.com/docs/extensions/reference/storage/#:~:text=to%20callback.-,get,-function

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM