Walls
Walls

Reputation: 159

Aync / Await return pending

Why is my Aync Await Function returning an Pending Promise ? i already tried .then statement but it doesn't work, here is my code :

  const findData = async () => {
    let query = await userSchema.findOne({ _id: research["uploaderID"] });
    return query;
  };

  research["uploaderInfo"] = findData();

  console.log(findData());

when i tried to console.log the findData, it just gave me this :

Promise { <pending> }
Promise { <pending> }

and when i tried to check the research object, it was empty, but when i tried to add a console.log(query) inside the findData() function, it gave me the expected result, which mean the query is correct, and this is an issue because of the async / await.

UPDATE

i tried @dai solution to add await when i tried to set my research like this

  const findData = async () => {
    let query = await userSchema.findOne({ _id: research["uploaderID"] });
    return query;
  };

  async () => {
    research["uploaderInfo"] = await findData();
  };

when i tried this, any code that i put inside the second nameless async function does not work, i tried to set the object to random string and it still doesn't changing

Upvotes: 0

Views: 86

Answers (1)

Dai
Dai

Reputation: 155270

Read this: https://stackoverflow.com/a/56590390/159145

Short answer: Run NodeJS 14.17 (or any version after 13.3+) with the flag --harmony-top-level-await and you can have this:

// program.js

const findData = async () => {
    let query = await userSchema.findOne({ _id: research["uploaderID"] });
    return query;
};

research["uploaderInfo"] = await findData();

console.log(research["uploaderInfo"]);

...or even just this (assuming your research and userSchema objects are trivially instantiated):

// program.js

research["uploaderInfo"] = await userSchema.findOne({ _id: research["uploaderID"] });

console.log(research["uploaderInfo"]);

Longer answer without NodeJS flags:

It looks like NodeJS 14.17 doesn't yet support "top-level await" (someone correct me if I'm wrong) but that's not a real problem: it just means you need to wrap all of your original top-level ("root function") code in an async function and invoke it immediately.

Like so (I've named the function entrypoint, though you can use an anonymous function if you like):

// program.js

async function entrypoint() {
    
    const research   = ...
    const userSchema = ...

    const findData = async () => {
        let query = await userSchema.findOne({ _id: research["uploaderID"] });
        return query;
    };
    
    research["uploaderInfo"] = await findData();

    console.log(research["uploaderInfo"]);
}

entrypoint();

Note that you can elide and inline findData's function and call userSchema.findOne directly:

// program.js

async function entrypoint() {

    const research   = ...
    const userSchema = ...    

    research["uploaderInfo"] = await await userSchema.findOne({ _id: research["uploaderID"] });

    console.log(research["uploaderInfo"]);
}

entrypoint();

Upvotes: 1

Related Questions