Home > Blockchain >  Wait for completion of callback function in HTTP request before continuing with for loop
Wait for completion of callback function in HTTP request before continuing with for loop

Time:12-19

I'm trying to run an HTTP request 3 times in node.js using the inbuilt HTTPS library, with each run having a different set of options. In order to move on to the next set of options after the completion of one execution, I"m using a for loop that increments once each run, for a total of 3 runs. However, instead of waiting for each run to finish before proceeding in the loop, it skips the first two calls completely and runs it 3 times with the third set of options. I've looked all over for an answer, anyone have any ideas/solutions?

    for(let i = 0; i < 3; i  ) {
        option = i;
        console.log("Calling with option "   i)
        await http.request(options[i], res => {
            let resp = '';
            res.on('data', function(chunk) {
                resp  = chunk;
            });
            res.on('end', async function () {
                let data = await JSON.parse(resp);
                if(option === 0) { //Bloxlink handler
                    console.log("Case 1: Bloxlink")
                    if(data.status === "error") {
                        returndata  = "Bloxlink returned no users"
                    } else {
                        returndata  = "\nBloxlink returned user with ID "   data.primaryAccount   " and username "   await noblox.getUsernameFromId(parseInt(data.primaryAccount))   "."
                    }
                } else if(option === 1) { //RoWifi handler
                    console.log("Case 2: RoWifi")

                    if(data.success === false) {
                        returndata  = "RoWifi returned no users"
                    } else {
                        returndata  = "\nRoWifi returned user with ID "   data.roblox_id   " and username "   await noblox.getUsernameFromId(data.roblox_id)   "."
                    }
                } else if(option === 2) { //Eryn handler
                    console.log("Case 3: Eryn")
                    if(data.status === "error") {
                        returndata  = "Eryn returned no users"
                    } else {
                        returndata  = "\nEryn returned user with ID "   data.robloxId   " and username "   data.robloxUsername   "."
                    }
                }
                console.log(returndata);
            });
            res.on('error', function () {
                channel.send('One or more APIs returned an error. The operation has been terminated.')
            });
        }).end();
        channel.send("Run "   i   " finished: "   returndata);
        console.log(returndata);
    }

CodePudding user response:

You could wrap it in a promise and then await it:

for(let i = 0; i < 3; i  ) {
    option = i;
    console.log("Calling with option "   i)
    await new Promise((resolve, reject) => {
        http.request(options[i], res => {
            let resp = '';
            res.on('data', function(chunk) {
                resp  = chunk;
            });
            res.on('end', async function () {
                let data = await JSON.parse(resp);
                if(option === 0) { //Bloxlink handler
                    console.log("Case 1: Bloxlink")
                    if(data.status === "error") {
                        returndata  = "Bloxlink returned no users"
                    } else {
                        returndata  = "\nBloxlink returned user with ID "   data.primaryAccount   " and username "   await noblox.getUsernameFromId(parseInt(data.primaryAccount))   "."
                    }
                } else if(option === 1) { //RoWifi handler
                    console.log("Case 2: RoWifi")
    
                    if(data.success === false) {
                        returndata  = "RoWifi returned no users"
                    } else {
                        returndata  = "\nRoWifi returned user with ID "   data.roblox_id   " and username "   await noblox.getUsernameFromId(data.roblox_id)   "."
                    }
                } else if(option === 2) { //Eryn handler
                    console.log("Case 3: Eryn")
                    if(data.status === "error") {
                        returndata  = "Eryn returned no users"
                    } else {
                        returndata  = "\nEryn returned user with ID "   data.robloxId   " and username "   data.robloxUsername   "."
                    }
                }
                console.log(returndata);
                resolve();
            });
            res.on('error', function () {
                channel.send('One or more APIs returned an error. The operation has been terminated.')
                reject();
            });
        }).end();
    }).then(() => {
        channel.send("Run "   i   " finished: "   returndata);
        console.log(returndata);
    });
}

But a cleaner approach would be to use a promise-based request library like fetch or axios.

  • Related