0

In my async function, I can't get true priority output.

Expected result is firstly {control : 1} and then {control : 2}.

But the result is vice versa.

How can I make it true ?

NodeJS Code

edit_settings = async function (params) {

    await User.updateOne({ _id: params.id }, query, (error, update_result) => {
        console.log({ control : 1 });
        if (error) return { success: false, error: { code: 1001 } };
        else return { success: update_result.nModified };
    });

    return await { control : 2 };
}

NodeJS Result

{ control : 2 }
{ control : 1 }

2 Answers 2

2

It doesn't look like User.updateOne returns a promise (could be wrong, but I'm guessing it doesn't), it accepts a callback, so await-ing it will do nothing.

EDIT: One way to solve it is to create a promise like this:

edit_settings = async function (params) {
    let res; // the `resolve` method of a promise
    const p = new Promise(r => res = r);
    User.updateOne({ _id: params.id }, query, (error, update_result) => {
        console.log({ control : 1 });
        res(); // resolve the promise
        if (error) return { success: false, error: { code: 1001 } };
        else return { success: update_result.nModified };
    });

    await p;
    return { control: 2 };
}

EDIT: Based on your comment that User.updateOne actually does return a promise, then you should be using it like this:

edit_settings = async function (params) {

    await User.updateOne({ _id: params.id }, query);
    console.log({control:1});
    return { control : 2 };
}

From the code you've shown, you actually aren't doing anything with the value you're returning from the promise, so I removed it from your code.

Sign up to request clarification or add additional context in comments.

3 Comments

Does your first example even work? You never assign res. Seems like it would be less confusing to just wrap the callback completely in the promise (e.g. await new Promise(res => User.updateOne(...)))
@JakeHolzinger - you're correct, typed it out too fast. I edited to show the reassignment. I also agree with your point, I think it'd be cleaner to just put the whole thing inside a promise rather than my capturing of the resolver. When will they just create a native freaking Deferred object? :)
A deferred object would certainly fit the solution more nicely.
0

I found the solition:

edit_settings = async function (params) {

    let result;

    ..

    result = await User.updateOne({ _id: params.id }, query).then(update_result => {
        result = { success: update_result.nModified };
    });

    ..

    return await result ;
}

5 Comments

You're grossly misunderstanding how async/await works. Why would you return await { control: 2 }? It's not a promise, it's a value (meaning return { control: 2} would accomplish the exact same thing as return await { control: 2 }.
@Adam Yes, you are right. I updated my answer before I see your comment. Thanks btw.
Super! So it does return a promise. The thing is, you're still misunderstanding await. await essentially unwraps a promise and, while it doesn't break anything, it's terribly confusing to use await and then next to each other. Do this: const result = await User.updateOne(...); console.log({control:1}); return { control: 2 };
I got this usage of async-await. Thanks for your help.
I would console.log blindly. Maybe if (result) return {control:1} else return {control:2}

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.