Reputation: 209
This issue has been driving me nuts for the last couple of days. I'm far from being a Javascript expert, maybe the solution is obvious but I don't see it.
What I basically try to do is :
If I download 1 item type, everything is OK. But if I download 2 types, then at some point in the processing loop within the first callback execution, exactly when the callback is executed a 2nd time for the 2nd type, then the test on type will indicate it's the 2nd type, while the items are of the 1st type...
Here is an extract of the code :
downloadType1();
downloadType2();
// 2nd argument of download() is the callback function
// 3rd argument is the callback function parameters
function downloadType1() {
// Some stuff here
let callbackParameters = ['type1', 'directory1'];
download('url', headacheCallback, callbackParameters);
}
function downloadType2() {
// Some the stuff here
let callbackParameters = ['type2', 'directory2'];
download('url', headacheCallback, callbackParameters);
}
async function download(url, callbackBeforeSave, callbackParameters) {
// Some stuff here
let response;
try {
response = await rp(url);
} catch (e) {
console.log("Error downloading data");
}
// Call callbacks before saving the data
if(callbackBeforeSave) {
let updatedResponse;
if (callbackParameters) {
updatedResponse = await callbackBeforeSave(response, ...callbackParameters);
} else {
updatedResponse = await callbackBeforeSave(response);
}
response = updatedResponse;
}
// Some stuff here with the post-processed data
}
async function headacheCallback(data, type, directory) {
for (item of data) {
// Some stuff here, include async/await calls (mostly to download and save files)
console.log(type, item.propertyToUpdate, item.child.propertyToUpdate);
// This is were my issue is.
// The test will success although I'm still the 'type1' loop. I know because the console.log above shows the item is indeed of type 'type1'
if (type === 'type2') {
item.child.propertyToUpdate = newUrl; // Will eventually fail because 'type1' items don't have a .child.propertyToUpdate property
} else {
item.propertyToUpdate = newUrl;
}
}
}
At some point, the output of console.log
will be :
type2 <valueOfTheProperty> undefined
which should be type2 undefined <valueOfTheProperty>
...
A quick thought : in the first version of the callback, I used the arguments
global variables in combination with function.apply(...)
. This was bad precisely because arguments
was global and thus was changed after the 2nd call...
But now I don't see anything global in my code that could explain why type
is changing.
Any help would be greatly appreciated.
Thanks!
Upvotes: 0
Views: 68
Reputation: 664195
I don't see anything global in my code that could explain why type is changing.
It's not type
that is changing. Your problem is item
that is an involuntary global:
for (item of data) {
// ^^^^
Make that a
for (const item of data) {
// ^^^^
And always enable strict mode!
Upvotes: 1
Reputation: 12542
This is a job for Promise.all
const p1 = new Promise((res, rej) => res());
Promise.all([p1, p2]).then((results) => results.map(yourFunction));
Promise.all will return an array of resolved or may catch on any rejection. But you don't have to reject if you setup your p1, p2, pn with a new Promise that only resolves. Then your function map can handle the branching and do the right thing for the right response type. Make sense?
Upvotes: 0