pitazzo
pitazzo

Reputation: 1212

Asynchronous function not waiting for Promise

I've written following asynchronious node.js function, which accesses to my database via Mongoose and thus is an async function):

function getWindSpeed(householdID){
    return new Promise(async function (resolve, _){
        const household = await Household.findById(householdID)
        resolve(stoch.norm(household.windSimulation.mu, household.windSimulation.sigma, 1))
    })
}

In the other hand, I have following function, which is also async because both accesses to the database and uses the previous function for each element in the database:

async function getMeanWindSpeed() {
    return new Promise(async function (resolve, reject){
        let numberOfHouseholds = 0
        let averageWind = 0.0
        console.log('Begin')
        await Household.find({}, async function (error, households) {
            if(error){
                reject(error)
            }else{
                numberOfHouseholds = households.length
                for(let i = 0; i < households.length; i++){
                    const speed = await wind.getWindSpeed(households[i].id)
                    console.log(speed)
                    averageWind += speed

                }
            }
        })
        averageWind = averageWind / numberOfHouseholds
        console.log('Finish')
        resolve(averageWind)
    })    
}

As you can see, I iterate over all the elements in the collection and apply the getWindSpeed() function, however it doesn't wait for its completion, as I get the following trace based on the console.log(...) debug messaged:

Begin
Finish
12.2322
23.1123
(more speeds)
...

Some more information that may be usefuk:

Thanks in advance

Upvotes: 2

Views: 91

Answers (2)

Terry Lennox
Terry Lennox

Reputation: 30675

If we don't pass a callback to .find() we'll get a promise returned, this makes the code a lot easier to read.

We could further simplify the function getMeanWindspeed since it becomes a simple wrapper for getAverageWindSpeed();

For example:

async function getAverageWindspeed() {
    let numberOfHouseholds = 0
    let averageWind = 0.0
    let households = await Household.find({});
    numberOfHouseholds = households.length
    for(let i = 0; i < households.length; i++){
        const speed = await wind.getWindSpeed(households[i].id)
        console.log(speed)
        averageWind += speed
    }
    return averageWind / numberOfHouseholds;
}

async function getMeanWindSpeed() {
    console.log('Begin')
    let averageWind = await getAverageWindspeed();
    console.log('Finish')
    return averageWind;
}

Upvotes: 2

xdeepakv
xdeepakv

Reputation: 8125

Why you are mixing await with promise. It is bad practice. If you can do same thing using await and async. See the below example.

const fakeDelay = () => new Promise(r => {
    setTimeout(() => r("data"), 1000);
})
const Household = {
    findById: () => fakeDelay()
}
async function getWindSpeed(householdID){
    const household = await Household.findById(householdID)
    console.log()
    //stoch.norm(household.windSimulation.mu, household.windSimulation.sigma, 1)
    return household;
}
const main = async () =>{
    getWindSpeed().then(console.log)
}
main()

// notice

async function getWindSpeed

will be by default promise

Upvotes: 0

Related Questions