0

I am quite new to promises and I think the implementation is quite weird also ;-)

I am working on a manifest 3 extension and need to make calls to chrome.storage.session.get and chrome.storage.local.get synchronously without callback seen from the caller side.

This is because a lot of the code in the big project is used both in the extension but also on normal web pages etc and it will be a nightmare to rewrite everything and test it again.

But my implementation test with async/await does not work as expected.

I have this function

const getObjectFromSessionStorage = async function(key) 
{
  return new Promise((resolve, reject) => 
  {
    try 
    {
      chrome.storage.session.get(key, function(value) 
      {
        if (chrome.runtime.lastError)
          reject(chrome.runtime.lastError);

        if(typeof(value[key]) === 'undefined')
          reject('undefined:' + key);

        resolve(value[key]);
      });
    } 
    catch (ex) 
    {
      reject(ex);
    }
  });
};

That I try to call synchronously in this function:

const getItemPromise = (session, key) => 
{
  let returnvalue;

  (async function ()
  {
    if(session)
    {
      returnvalue = await getObjectFromSessionStorage(key);
    }
    else
    {
      returnvalue = await getObjectFromLocalStorage(key);
    }
  }());

  //debugger;

  return returnvalue;

But it only work if I stop in the debugger just before "return returnvalue;" If I do not it will return right away.

  chrome.storage.session.set({'TEST': 'HELLO'}, () => 
  {
          if (chrome.runtime.lastError)
              console.log(chrome.runtime.lastError);
    
          chrome.storage.session.get('TEST', (value) => 
          {
            if (chrome.runtime.lastError)
              console.log(chrome.runtime.lastError);
    
            console.log(value);
          });
    
          console.log(getItemPromise(true, 'TEST'));
 });

E.g without debugger stop console.log(value); is returned last and console.log(getItemPromise(true, 'TEST')); is returned first with undefined as result. With debugger stop console.log(getItemPromise(true, 'TEST')); is returned last and with the correct content.

I do not understand why - hope somebody can help me out here

Beast
  • 271
  • 2
  • 5
  • 15
  • 2
    You can’t really convert async code to synchronous. In this case the problem is that `return returnvalue;` happens prior to the async iife completing. – James Dec 05 '22 at 16:37
  • you need to implement the `resolve` and `reject` using this `returnvalue = await getObjectFromSessionStorage(key).then(alert,alert);` – Yasser CHENIK Dec 05 '22 at 16:54
  • @YasserCHENIK .then require a function callback again - so what have I gained – Beast Dec 05 '22 at 17:07
  • @James It is a self callable function where I have await inside - shall it not wait before returning? – Beast Dec 05 '22 at 17:09
  • The iife itself isn’t awaited. If you did, you’d still need getItemPromise to be async, since you’d have used await in it. – James Dec 05 '22 at 17:37
  • @James Inside getItemPromise I have a (async function () so await is in a async function – Beast Dec 05 '22 at 17:49
  • Yep but the async iife is not awaited. – James Dec 05 '22 at 17:50
  • Thats the problem I try to solve. – Beast Dec 05 '22 at 17:52
  • You can’t without making getItemPromise async. – James Dec 05 '22 at 17:54
  • I am unable to see the difference. I can not make the top function async as I then have to call await a million places in my code. But I have async function and await further down – Beast Dec 05 '22 at 18:01
  • What are you trying to accomplish in the end? Also, `chrome` API already returns a Promise, no need to promisify it, unless you want your MV3 extension to run in outdated Chrome 80-90 but that'd be weird because for old Chrome it's better to use MV2 instead of the partially implemented MV3. Maybe look at [How do I return the response from an asynchronous call?](https://stackoverflow.com/q/14220321) – wOxxOm Dec 05 '22 at 18:40
  • @wOxxOm Thank you for the link and I do understand the link and I have also tried the promise returned from the API. I think at its core my problem is that I seam unable to convert the callback/promise nature to a function that return the result as needed by all my existing code? – Beast Dec 06 '22 at 06:51
  • Then maybe show the existing code? It should be as simple as `let {foo} = await chrome.storage.session.get('foo');` – wOxxOm Dec 06 '22 at 07:17
  • @wOxxOm The current function is very simple "value = getvalue(key);" but you cannot use await directly as this has to be inside a async function. If chrome.storage.session.get was available in a normal web page I would be able to convert it all. But because of MV3 I have to have 2 different logics in the getvalue function because of the shared code. It does not matter that the storage is diffferet as it is session data. – Beast Dec 06 '22 at 07:26
  • As mentioned in the comments you can't use this API synchronously i.e. you need `await` or `.then()`. – wOxxOm Dec 06 '22 at 07:28
  • That is also what I do - but it does not wait. E.g. how to convert from promise/callback logic to a function that return a value. Have tried in many different ways including .then() – Beast Dec 06 '22 at 07:31

0 Answers0