Skip to content

Instantly share code, notes, and snippets.

@jakearchibald
Created March 27, 2014 15:31
Show Gist options
  • Star 74 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save jakearchibald/31b89cba627924972ad6 to your computer and use it in GitHub Desktop.
Save jakearchibald/31b89cba627924972ad6 to your computer and use it in GitHub Desktop.
function spawn(generatorFunc) {
function continuer(verb, arg) {
var result;
try {
result = generator[verb](arg);
} catch (err) {
return Promise.reject(err);
}
if (result.done) {
return result.value;
} else {
return Promise.resolve(result.value).then(onFulfilled, onRejected);
}
}
var generator = generatorFunc();
var onFulfilled = continuer.bind(continuer, "next");
var onRejected = continuer.bind(continuer, "throw");
return onFulfilled();
}
@Vaishali-0902
Copy link

Thanks for this gr8 article.
I am using ShowModalDialog Polyfill to make it compatible with latest versions of chrome. But when I included
'spawn *function(){}'
in my code. the jsp is not loading in IE. Can you please help? I think * is the problem. Is there any other alternative?
eval() is also not working.
Thanks for help!

@boichee
Copy link

boichee commented Oct 1, 2015

@Vaishali-0902:
I'd like to answer your question for you, and I'm going to try, but it's hard to know what to say. Are you working in Chrome like you state up front, or are you actually trying to do something in IE? (This makes a huge difference). Also, what version of Chrome/IE (again, big difference)?

Then, maybe you just made a typo, or maybe you just shouldn't be surprised that ES6 features aren't working properly in IE. But either way in your post you said you tried to write spawn * function()

If I'm to take you at your word, then you're missing a few basic things that would definitely cause issues:

  1. You're missing the () that would actually call the spawn function, as in spawn(function *() { } )
  2. Your syntax for creation of a generator function in ES6 isn't right. You'd create the generator like this, with the asterisk after the function.
function *() { /* generator-y stuff */ }

// So you need to write
var whatever = spawn(function *() {
  // more stuff
});

You can read more about this on MDN.

But to answer your question, per the ES6 spec, there is (sort of) an alternative to using the * syntax, the GeneratorFunction constuctor. It's definitely not ideal though, since you'd have to pass the function body as a string. Really unwieldy, and I'd really recommend you take a look at your syntax before giving this version a shot:

var foo = new GeneratorFunction(param, param1, "var x = 42; var y = 'Answer to The Ultimate Question of Life, the Universe, and Everything'; if (x === 42) return y;");

I think you'll agree that's not a way to go.


Finally, why are you using eval()? Some say it's evil. I say it can be EVIL. But seriously, read this and make sure that you're not misusing eval.

@hanfeisun
Copy link

Just curious why it is called spawn... Do it has any similarity with this spawn which loads and executes a new child process..

@jayakrishna89
Copy link

Thank you @jakearchibald for the showModalDialog replacement. It's really helpful. Glad I was able to find this simple solution.

@taralx
Copy link

taralx commented Apr 29, 2017

@jakearchibald I have this. Although it doesn't handle returning a value, it has some advantages. :-)

function spawn(gen) {
	return function(...args) {
		let iter = gen(...args);
		function step({value, done}) {
			if (!done) value.then(v => iter.next(v), e => iter.throw(e)).then(step);
		}
		step(iter.next());
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment