Async await not working?

Could someone share a light on why res2 and res3 are not passed within async and await properly?

import {Meteor} from 'meteor/meteor';


Meteor.methods({

    async testTopLevel() {
        const res1 = await Meteor.call('myFirstAsyncFunc', 1);      // x is : 7 
        const res2 = await Meteor.call('mySecondAsyncFunc', res1);  // y is : NaN
        const res3 = await console.log('Top results is :', res2);   // Top results is : { _45: 0, _81: 0, _65: null, _54: null }
        return res2;
    },

    async myFirstAsyncFunc (x)
    {
        var value = await Promise
            .resolve(x)
            .then(x => x * 2)
            .then(x=> x + 5)
            .then(x=> x * 2)
            .then(x=> x / 2)
            
        return value;
    },

    async mySecondAsyncFunc (y) {
        var value = await Promise
            .resolve(y)
            .then(y => y * 2)
            .then(y=> y + 5)
            .then(y=> y * 2)
            .then(y=> y / 2)
            
        return value;
    }
});

Meteor.startup(() => {

    Meteor.call('testTopLevel');

});

With output in this order:

I20160711-19:01:15.192(1)? x is : 7
I20160711-19:01:15.195(1)? Top results is : { _45: 0, _81: 0, _65: null, _54: null }
I20160711-19:01:15.196(1)? y is : NaN

async functions return a promise.

async mySecondAsyncFunc (y) {
        var value = await Promise
            .resolve(y)
            .then(y => y * 2)
            .then(y=> y + 5)
            .then(y=> y * 2)
            .then(y=> y / 2)
            
        return value;
    }

This returns a promise on ‘value’, not value itself

And methods don’t return values. They take a callback

Meteor.call('todos.updateText', {
  todoId: '12345',
  newText: 'This is a todo item.'
}, (err, res) => {
  if (err) {
    alert(err);
  } else {
    // success!
  }
});
const res3 = await console.log('Top results is :', res2);   
// Top results is : { _45: 0, _81: 0, _65: null, _54: null }

There is nothing to wait for here.

Just repeating (a simplified verion of) the example given here

import { Meteor } from 'meteor/meteor'

if (Meteor.isServer) Meteor.methods({ 'normal' : () => 1 })

if (Meteor.isClient)
{
  const call = method_name => new Promise ((resolve, reject) => {
    Meteor.call(method_name, (e, r) => resolve(r))
  })

  const f = async () => {
    const r = await call ('normal')
    console.log (r)
  }
  f ()
}

It prints 1

Hi Diego,

Which Promise library are you using? The ecmascript, Bluebird or RSVP?

I thought the use of Promise and await async is so that you don’t have to use callbacks and avoid the righthand drift?

“ecmascript”, which is installed with Meteor by default.

const r = await call ('normal')
console.log (r)

This code doesn’t have any callbacks and looks fairly sequential. The only problem with promises is they automatically chain : the second you use await the function where that code is used has to return a promise.

The only way out of the chain and call your code from a “normal” code is to call a function that discards it’s result. Which is why you have the code

  const f = async () => {   // <-- returns a promise
    const r = await call ('normal')
    console.log (r)
  }
  f () // <-- discards the promise 

That said, there is no miracle. Promises only give you a placeholder for your function to return something while the final value is computed. They don’t magically transform JavaScript into a concurrent programming language.

1 Like