user3582315
user3582315

Reputation: 209

Promises messing up?

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 :

  1. download items in paralell, each request being made for a given item type (type1, type2) with different properties.
  2. Once downloaded, execute a callback function to post-process the data (this is the same function with different parameters and with a test on the item type in order to have different processing)
  3. Save the item

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

Answers (2)

Bergi
Bergi

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

4m1r
4m1r

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

Related Questions