How to deal with async code?

Hi everyone,

as I’m starting a new project, I want to do everything in a future proof way. I’ve searched the web a bit and I just want to make sure that I’m on the right track.

In the past I’ve used Meteor’s Meteor.wrapAsync quite a lot to get nicer code, but this can quickly lead to situations where you have to use Meteor.bindEnvironment for every second callback, which isn’t nice. It’s very Meteor specific as well.

Promises seem to have been around for some while through libraries, and now they’re natively available in ES6. I like the syntax and chaining Promises can make the code really clean.

I’ve now read about async/ await, which seems to be a syntactical alternative to calling Promises coming with ES7.

Is there any way of dealing with async code I missed? I’m wondering what to use now. I think Promises are a safe bet, as they provide a good API and can still be used with the newer async/ await syntax in the future.

So that’s what I’d try outside of Meteor, but I’m not sure what I can use with it. There is a promise package, but where can I actually use it? Does it work with Meteor.methods?

@benjamn Maybe it’s already there and I’ve just missed it, but it would be great to have an article/ overview/ guide on how to deal with async code in Meteor > 1.3.

Have a great day :slight_smile:

1 Like

This definitely deserves a longer post, but the short answer is: yes, use Promises!

The Meteor promise package does two things:

  1. Provides a polyfill implementation for the Promise constructor if necessary, but also uses any existing global Promise constructor.
  2. Wraps Promise.prototype.then so that every callback runs in a recycled Fiber drawn from a pool of Fibers, giving you all the benefits of Meteor.bindEnvironment with none of the boilerplate.

In other words, if you’re comfortable using Promises, you can safely forget about Meteor.wrapAsync, .bindEnvironment, and even Fibers.

An even easier way to use Promises is via async functions.

I have an old pull request that allows Meteor.methods to return Promises, and implements Meteor.callAsync as an API for interacting with those promises on the client. I should probably revisit that, though you can see from the comments why the design didn’t feel quite ready.