Glad to hear it. I do it all the time, particularly with aggregations. Thought I was doing something wrong!
Just to finish this off, here’s an example showing one way of managing generators in methods and allowing for multiple clients. I haven’t done much to clean this code up:
// server/main.js
import { Meteor } from 'meteor/meteor';
function* gen() {
yield(1);
yield(22);
yield(333);
return null;
}
const g = {}; // Hash of generator instances
Meteor.onConnection(connection => {
connection.onClose(() => {
if (connection.id && g[connection.id]) {
console.log(`Destroying generator for ${connection.id}`);
delete g[connection.id];
}
});
});
Meteor.methods({
next() {
if (!g[this.connection.id]) g[this.connection.id] = gen();
return g[this.connection.id].next().value;
}
});
Now let’s hope the server has enough free memory available
Please think twice before using the awesome code posted above. If you’re doing some external api requests between yield 1
and yield 2
, and storing let’s say 1 MB of data per user. The moment you do have 100 users online, all using this method, you’ll simply need 100 MB purely for remembering that data.
100 MB doesn’t sounds scary, but 100 users can be 500, en 1 MB can be 5 MB.
Just trying to say; please understand that you will loose the benefits of single threaded design of Node, as you’re faking threads this way. use with caution
This is exactly how Meteor manages stateful data. It’s no different to the merge box, for example.
And what is “faking threads”? I don’t know what you mean by that. Node remains single threaded - just as it does with Fibers or Promises.
Just wanted to thank @tzu for catching an issue with dmihal:generator-method
. I’ve fixed the issues, feel free to try it out if you want an easy way to use generators as methods!