1

This function takes 2 asynchronous callbacks. I am not sure why, but when these callbacks are called, the promises they await aren't being awaited correctly. I'm thinking it may have something to do with the way I'm calling them. I am not very familiar with the promise API so I kind of just hacked this together. If someone could tell me if I am doing something wrong, I would really appreciate it.

   async queryTasks(handleCommand, handleSubmission) {
        const D = new Date().getTime();
        const promises = [];
        while (!this.tasks.isEmpty()) {
            const task = this.tasks.dequeue();
            // If not a submission
            if (task.item.body) {
                const command = new Command().test(task.item.body);
                if (command) { // If the item received was a command, return the command, the item, and priority
                    const T = {
                        command: command,
                        item: task.item,
                        priority: task.priority,
                        time: D
                    }
                    console.log("Calling back with handleCommand(task)".bgMagenta.white);
                    promises.push(handleCommand(T));
                }
            } else if (task.item.title) { // Task was a submission
                console.log("Calling back with handleSubmission".bgMagenta.black);
                const T = {
                    item: task.item,
                    priority: task.priority,
                    time: D
                }
                promises.push(handleSubmission(T));
            }
        }
        return Promise.all(promises);
    }

Or maybe it's the way I'm calling it queryTasks()?

/* [Snoolicious Run Cycle] */
const INTERVAL = (process.env.INTERVAL * 1000);
async function run() {
        console.log("Running Test!!!".green);
        await snoolicious.getMentions(2);
        console.log("Size of the queue: ", snoolicious.tasks.size());
        await snoolicious.queryTasks(handleCommand, handleSubmission);
        console.log(`Finished querying tasks. Sleeping for ${INTERVAL/1000} seconds...`.rainbow);
        setTimeout(() => {
            return run()
        }, (INTERVAL));
    }
    (async () => {
        await run();
    })();

The output:

Preparing new database...
SELECT count(*) FROM sqlite_master WHERE type='table' AND name='saved';
Preparing statements...
Running Test!!!
MentionBot --Assigning hte FIRST utc...
Size of the queue:  2
Snoolicious Querying Tasks!
Calling back with handleCommand(task)
Bot -- handling a command! { directive: 'positive', args: [] }
Test passed
getting the parent submission...
Calling back with handleCommand(task)
Bot -- handling a command! { directive: 'positive', args: [] }
Test passed
getting the parent submission...
Finished querying tasks. Sleeping for 30 seconds...
Got this parent:  Comment {...

Handling commands and getting parent submission: (snoolicious.requester = snoowrap.requester)

async function handleCommand(task) {
    let id = `${task.item.parent_id}${task.item.created_utc}${task.item.id}`;
    const checkedId = await db.checkID(id);
    if (task.item.subreddit.display_name === process.env.MASTER_SUB) {
        try {
            validateCommand(task.command);
            const parent = await getParentSubmission(task.item);
            console.log("Got this parent: ", parent);
            console.log("Checking against this item: ", task.item);
            await checkUserRatingSelf(task.item);
            await checkTypePrefix(task.item);
        } catch (err) {
            await replyWithError(err.message);
        }

    } else {
        console.log("id HAS been seen: id ", checkedId);
    }
}

// Get a parent submission:

async function getParentSubmission(item) {
    console.log("getting the parent submission...".magenta);
    if (item.parent_id.startsWith('t3_')) {
        const rep = item.parent_id.replace('t3_', '');
        const parent = await snoolicious.requester.getSubmission(rep);
        return parent;
    } else if (item.parent_id.startsWith('t1_')) {
        const rep = item.parent_id.replace('t1_', '');
        const parent = await snoolicious.requester.getComment(rep);
        return parent;
    }
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
J. Carpenter
  • 91
  • 1
  • 9
  • 2
    Do those *handle* functions actually return promises? – charlietfl Oct 22 '20 at 00:04
  • What's the output? Do you get any errors? – IvanD Oct 22 '20 at 00:07
  • they are asynchronous functions, that should mean I don't have to implicity tell it to return a promise? I try telling it to return Promise.resolve("resolved") at the end of the function, but still the output is this: it runs all the synchronous things then when it gets to an async method it just continues on and will print the response when it arrives. No errors, just slips past where its supposed to wait. – J. Carpenter Oct 22 '20 at 00:14
  • @IvanD I edited with output. It is supposed to be awaiting the parent submission. – J. Carpenter Oct 22 '20 at 00:22
  • Please add the code for `handleSubmission` function – IvanD Oct 22 '20 at 00:28
  • You shouldn't declare a function `async` if it returns a promise explicitly. You're wrapping the promise inside another promise, and not resolving the innner one. – Barmar Oct 22 '20 at 00:29
  • 2
    We need to see the code for both `handleSubmission()` and `handleCommand()` as the problem is likely in there. They are likely not returning a promise that is actually connected to when their asynchronous operations are done. – jfriend00 Oct 22 '20 at 00:33
  • I added the handleCommand function. Submission function isn't being triggered by this code anyway. The database function is resolving correctly. It seems to be just the snoowrap one that's not working right. Unless the db is resolving so quickly that it just prints in time? – J. Carpenter Oct 22 '20 at 01:04
  • 1
    handleCommand has no returned promise so Promise.all() would just see `undefined` and resolve immediately. Seems you have some fundamental misunderstandings about how `async/await` work. Another that makes no sense is `await run();` as well as the `return` in setTimeout which has nowhere to return to – charlietfl Oct 22 '20 at 01:07
  • @charlietfl the return run() is a recursive function. It calls itself at INTERVAL. AFAIK any function marked async will implicitly return a promise. See [here](https://stackoverflow.com/questions/35302431/async-await-implicitly-returns-promise). If I am misunderstanding something, please tell me. – J. Carpenter Oct 22 '20 at 01:18
  • Fine but a return in setTimeout is useless as is using `await` when calling run(), nothing is returned to await on. This is the same pattern you used in `handleCommand ()` incorrectly and is what is leading you to unexpected behaviors – charlietfl Oct 22 '20 at 01:20
  • Do you realize that you can't just slap `await` in front of an asynchronous function and automatically have it wait for that function? The function itself has to be explicitly designed to make that work such that it returns a promise that is resolved or reject when the asynchronous work is done. You can use `async` functions to help with this, but that is not all you have to do. – jfriend00 Oct 22 '20 at 01:59
  • What is `snoolicious`? There are now lots more functions from that that we can't see the code for that you're using `await` with. To know where things are going haywire, we have to be able to see the code for the entire call chain. – jfriend00 Oct 22 '20 at 02:00

0 Answers0