How to sync asynchronous calls content script <- background?

2,111 views
Skip to first unread message

Goodwine

unread,
Aug 21, 2010, 8:44:18 PM8/21/10
to Chromium-extensions
Hiya, I have asked this before, and I had some replies and the topic
went other way because it wasn't dealing exactly with this.
Ok, here is the thing, I'm using an options page which stores info in
local storage, then I pass it to the content scripts using
sendRequest, like this:

// script.js //
var x;
function getLocalStorageValue(key)
{
chrome.extension.sendRequest({'key' : key}, function (value) {
x = value;
});
}

// background.html //
chrome.extension.onRequest.addListener(function (request, sender,
response) {
if(request.key != null)
response(localStorage.getItem(request.key));
else
response();
});

Then the scripts needs like ASAP this values for several purposes, and
should not advance until it has this values.
However it advances because the call is asynchronous, and I have a
race condition D:

How would I "pause" script.js so it waits until x gets a value?
I tried something stupid like while(!x);
But then the whole thing hangs up as if the response wouldn't start.

And I need this x for several other things, so I can't have all of the
other code inside the response
What should I do?

PS it actually works the way it should when I'm doing several other
things before I actually need it, but when I need it ASAP it shows the
problem with this race condition xD

Daniel Wagner-Hall

unread,
Aug 21, 2010, 8:51:46 PM8/21/10
to Goodwine, Chromium-extensions
If you put your code into functions, you can just call those functions
in the callbacks... Yay code-reuse!

> --
> You received this message because you are subscribed to the Google Groups "Chromium-extensions" group.
> To post to this group, send email to chromium-...@chromium.org.
> To unsubscribe from this group, send email to chromium-extens...@chromium.org.
> For more options, visit this group at http://groups.google.com/a/chromium.org/group/chromium-extensions/?hl=en.
>
>

Goodwine

unread,
Aug 21, 2010, 8:54:19 PM8/21/10
to Chromium-extensions
I guess I may have to rethink all the solution again xD
So, with this I guess there is no way to wait without something ugly
like sleeping right?

On Aug 21, 7:51 pm, Daniel Wagner-Hall <dawag...@gmail.com> wrote:
> If you put your code into functions, you can just call those functions
> in the callbacks... Yay code-reuse!
>
> > To post to this group, send email to chromium-extensi...@chromium.org.
> > To unsubscribe from this group, send email to chromium-extensions+unsubscr...@chromium.org.

Daniel Wagner-Hall

unread,
Aug 21, 2010, 9:25:08 PM8/21/10
to Goodwine, Chromium-extensions
The only way to "sleep" in Javascript is to setTimeout, which will
make a call to a function a specified number of milliseconds in the
future - you would still need to use callbacks. In short - get used
to asynchronicity

> To post to this group, send email to chromium-...@chromium.org.
> To unsubscribe from this group, send email to chromium-extens...@chromium.org.

Goodwine Grim

unread,
Aug 21, 2010, 10:39:37 PM8/21/10
to Daniel Wagner-Hall, Chromium-extensions
I see, well, thanks for your reply, I actually already thought on how to do it

PhistucK

unread,
Aug 23, 2010, 4:21:18 AM8/23/10
to Goodwine Grim, Daniel Wagner-Hall, Chromium-extensions
And you may share it with the class. ;)

☆PhistucK

Goodwine Grim

unread,
Aug 23, 2010, 11:59:50 AM8/23/10
to PhistucK, Daniel Wagner-Hall, Chromium-extensions
Oh well instead of having the function return a value to be used by a DOM element, why not send the DOM elements that will need the value, as arguments of the function.

and the function may be like
// script.js //
arr = ['x','y','z', element];
var x,y,z, element=document.getElementById('hi');
chrome.extension.sendRequest( 'keys':arr, doStuff);
function doStuff(values, element) {
  //do something with values and element id 'hi'
}

// background.html //
chrome.extension.onRequest.addListener(function (request,sender,response) {
  if(request.keys) {
    var ret = [];
    for(var i=0; i<request.keys.length-1; i++)
      ret.push(localStorage.getItem(request.keys[i]));
    response(ret, request.keys[request.keys.length-1]);
  }
  else
    response();
}

I'm not sure if what I did is the best way to solve my issue, but it at least works for me xD, mine looks a bit different but what I just wrote is basically it.

Where I live there is a phrase that would be translated to English as:
"If Mahoma doesn't go to the mountain, the mountain goes to Mahoma"

I guess thats how I will explain it.

Goodwine Grim

unread,
Aug 23, 2010, 12:01:45 PM8/23/10
to PhistucK, Daniel Wagner-Hall, Chromium-extensions
// script.js //
var element=document.getElementById('hi');
arr = ['x','y','z', element];
chrome.extension.sendRequest( 'keys':arr, doStuff);
function doStuff(values, element) {
  //do something with values and element id 'hi'
}

woops, I guess there was a mistake xD
this should look better and... work haha

PhistucK

unread,
Aug 23, 2010, 12:16:20 PM8/23/10
to Goodwine Grim, Daniel Wagner-Hall, Chromium-extensions
Not so sure this would work, since you cannot send an element. The message is serialized as JSON, elements do not fit into JSON strings.
So it is weird that you said you managed.

☆PhistucK

Goodwine Grim

unread,
Aug 23, 2010, 12:31:24 PM8/23/10
to PhistucK, Daniel Wagner-Hall, Chromium-extensions
I'm let me check the code, sec...

Mm.. I think its a bit diferent from what I wrote lol
let me paste the code directly...

// script.js //
var tmlIcon, pskIcon, exhIcon;
function linkElement(element)
{
   if(!tmlIcon || !pskIcon || !exhIcon)
{
var send = new Array('tml', 'exh', 'psk');
chrome.extension.sendRequest({'icons' : send}, function (value) {
tmlIcon = value[0];
exhIcon = value[1];
pskIcon = value[2];
linkElement(element)
});
return false;
}
   /*
        I think that with this you can finally do stuff with the values and the element
   */
}

// background //
chrome.extension.onRequest.addListener(function (request, sender, response){
if(request.icons != null)
{
x = [];
for(var i in request.icons)
x[i] = localStorage.getItem(request.icons[i]);
callback(x);
}
else callback();
});

Sorry for the bad info, I thought the other way would work too D: and I didn't remember the code at all so I invented it xD but well, here it is, I didn't include what I do with that info, but well...

PhistucK

unread,
Aug 23, 2010, 12:36:37 PM8/23/10
to Goodwine Grim, Chromium-extensions
Well, I do not really see anything synchronous in this code, but, oh, well. :)

☆PhistucK

Goodwine Grim

unread,
Aug 23, 2010, 12:55:10 PM8/23/10
to PhistucK, Chromium-extensions
I wanted to return the values and use it outside the function, which caused race conditions due asynchronism, so, instead of returning a value and process, I send the thing (in this case the element) that will be processed with the values and they get done in a different plane as the main code.

the main code was like - element.innerHTML = linkElement();
now its like - linkElement(element);
I'm not sure how to say it xD
But I'm happy that I'm learning.
Reply all
Reply to author
Forward
0 new messages