For more detailed discussion about asynchronous code in JavaScript see:
It logs an empty string. Why is that?
Because you set contentHtml = '';
. At the time that you console.log(contentHtml);
, it has not changed.
What is the proper way of putting this into the variable contentHtml
?
The way you are doing it assigns it into contentHtml
just fine.
Your issue is not functionally how to assign a value to contentHtml
. It is not an issue specific to writing a Firefox add-on. Your issue is understanding the flow of asynchronous programming.
JavaScript tends to be written with unnamed functions defined inline where they are used. While this is more compact, I find that it tends to result in newer programmers not as readily understanding the execution flow of a program that is asynchronous.
I have re-written your code so it is more clear as to what happens when:
var tabs = require("sdk/tabs");
var contentHtml = '';
function workerAttachedToTabWhenTabActivated() {
//This is executed every time a tab is activated.
//It is not executed until that time.
self.port.emit("html", document.body.innerHTML);
}
function receiveHtmlMessageFromWorkerViaPortOn(message) {
//This is executed only when we receive a message via port.on that is named "html".
//It is not executed until such a message is received.
//We set contentHtml to message here. While the contentHtml variable is defined in the
// containing code, setting it here does not, currently, do us any good because
// the rest of the program has already completed by the time this is executed.
contentHtml = message;
//Show that we actualy do set contentHtml.
console.log("contentHtml after receiving html message:" + contentHtml);
}
tabs.on('activate', function(tab) {
var worker = tab.attach({
contentScript: 'workerAttachedToTabWhenTabActivated();'
});
worker.port.on("html", receiveHtmlMessageFromWorkerViaPortOn(message))
});
//When we execute the following statement contentHtml is still "".
//When we get here, we have set up our functions that are executed upon a tab becoming
//active, but that code has not yet been executed because no tab became active in the small
//amount of time between setting up those listeners and this executing.
console.log("contentHtml after setting up tab.attach:" + contentHtml);
As you should be able to see, setting the global variable contentHtml
to the message
does not do much good in this instance because execution has already passed the statement
console.log("contentHtml after setting up tab.attach:" + contentHtml);
by the time contentHtml
is set to the message
. Setting the global variable contentHtml
to the message
would only do some good if there were other asynchronous code which might execute later in which it was desired to know what the most recent html
message
that had been received was.
In general, everything that depends on the contents of the html
message
should be put in the function that is executed when that message is received.