Using Async Functions
Meteor now uses the Promise
API for all asynchronous operations.
This means that for many functions, for example the Meteor.call
function, you have the Meteor.callAsync
counterpart, that returns a promise of the result.
You can promisify any function that takes a callback as its last argument, with the Meteor.promisify
function.
for example, you can make Meteor.loginWithPassword
return a promise like this:
import { Meteor } from 'meteor/meteor';
loginWithPasswordAsync = Meteor.promisify(Meteor.loginWithPassword);
const login = async () => {
try {
await loginWithPasswordAsync('username', 'password');
console.log('Logged in');
} catch (error) {
console.error('Login failed', error);
}
};
For promises in general, you can use the await
keyword to wait for the promise to resolve.
const delay = async () => {
console.log('Waiting...');
await new Promise(resolve => setTimeout(resolve, 1000));
console.log('Done waiting');
};
await delay(); // it will wait for 1 second before logging 'Done waiting'
Normally you should await
the promise inside an async
function, but you can also use the then
method to handle the promise resolution.
const delay = () => {
console.log('Waiting...');
return new Promise(resolve => setTimeout(resolve, 1000));
};
delay().then(() => console.log('Done waiting'));
console.log('End of the function'); // this will be logged before 'Done waiting'
With the await
keyword, the code will wait for the promise to resolve before continuing.
This is essential for Meteor methods, as they are asynchronous by nature.
const callMethod = async () => {
try {
const result = await Meteor.callAsync('myMethod', 'arg1', 'arg2');
console.log('Method result:', result);
} catch (error) {
console.error('Method error:', error);
}
};
await callMethod();
As mentioned in the call x callAsync you should await for the Meteor.callAsync
function to resolve.
Handling errors
When using await
, you can use a try
/catch
block to handle errors.
In the past you would have to pass a callback to handle errors, but now you can use the catch
block to handle errors.
import { Meteor } from 'meteor/meteor';
Meteor.call('myMethod', 'arg1', 'arg2', (error, result) => {
if (error) {
console.error('Method error:', error);
} else {
console.log('Method result:', result);
}
});
Now, with await
you can use a try
/catch
block to handle errors.
import { Meteor } from 'meteor/meteor';
try {
const result = await Meteor.callAsync('myMethod', 'arg1', 'arg2');
console.log('Method result:', result);
} catch (error) {
console.error('Method error:', error);
}
You also can use the then
method to handle the promise resolution.
import { Meteor } from 'meteor/meteor';
Meteor.callAsync('myMethod', 'arg1', 'arg2')
.then(result => console.log('Method result:', result))
.catch(error => console.error('Method error:', error));
Async context
To use await, you need to be inside an async
function.
const myFunction = async () => {
console.log('Waiting...');
await new Promise(resolve => setTimeout(resolve, 1000));
console.log('Done waiting');
};
Without the async
keyword, you will get a syntax error.
const myFunction = () => { syntax error!
console.log('Waiting...');
await new Promise(resolve => setTimeout(resolve, 1000));
console.log('Done waiting');
};
You context must be async
to use the await
keyword.
for example in meteor 2 this code would work:
import { Meteor } from 'meteor/meteor';
const someFunction = () => {
Meteor.call('myMethod', 'arg1', 'arg2', (error, result) => {
if (error) {
console.error('Method error:', error);
} else {
console.log('Method result:', result);
// do something with the result
}
});
};
Now you need to make it async
to use the await
keyword.
import { Meteor } from 'meteor/meteor';
const someFunction = async () => {
try {
const result = await Meteor.callAsync('myMethod', 'arg1', 'arg2');
console.log('Method result:', result);
// do something with the result
} catch (error) {
console.error('Method error:', error);
}
};