How To Synchronously Declare Js Object And Then Edit A Property Of The Object With Data That Is Dependent On A Concurrent Operation
Solution 1:
This is the classic closure problem. The function you're passing as the done
handler has an enduring reference to the eventObject
variable (and there's only one, it's not loop-specific), so only the last one gets filled in. (This is usually what you want, but not in this case.)
You can work around it with a builder function that closes over something else (usually an argument):
for (var i = 1, l = rawEventbriteData.length; i < l; i++){
var eventObject = {
name: rawEventbriteData[i].event.title,
images: []
};
var jsdom = require('jsdom');
var arrayOfImgs = [];
jsdom.env({
html: rawEventbriteData[i].event.description,
scripts: ["http://code.jquery.com/jquery.js"],
done: buildDoneHandler(eventObject)
});
}
functionbuildDoneHandler(evtobj) {
returnfunction(errors, window) {
window.$('img').each(function(){
var imgSrc = window.$(this).attr('src');
console.log(imgSrc);
evtobj.images.push(imgSrc);
});
};
}
Note that the functon returned by buildDoneHandler
closes over and uses evtobj
(the argument we give buildDoneHanlder
) rather than eventObject
. Since the argument is specific to each call to buildDoneHandler
, we update the right event object.
This can also be done with ES5's Function#bind
although it can get confusing when there are other arguments, and creating functions that you bind
in a loop is wasteful (not that it usually matters):
for (var i = 1, l = rawEventbriteData.length; i < l; i++){
var eventObject = {
name: rawEventbriteData[i].event.title,
images: []
};
var jsdom = require('jsdom');
var arrayOfImgs = [];
jsdom.env({
html: rawEventbriteData[i].event.description,
scripts: ["http://code.jquery.com/jquery.js"],
done: function(evtobj, errors, window) {
window.$('img').each(function(){
var imgSrc = window.$(this).attr('src');
console.log(imgSrc);
evtobj.images.push(imgSrc);
});
}.bind(null, eventObject)
});
}
Function#bind
returns a function that, when called, will call the original function with a specific this
value and with any further arguments you give it at the beginning of the arguments list.
Post a Comment for "How To Synchronously Declare Js Object And Then Edit A Property Of The Object With Data That Is Dependent On A Concurrent Operation"