-
Notifications
You must be signed in to change notification settings - Fork 643
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The .then
and .catch
methods in runtime/OutMixins.js
are broken
#442
Comments
.then
method in runtime/OutMixins.js
is broken.then
and .catch
methods in runtime/OutMixins.js
are broken
So I just now realized why that was throwing an error: The stream itself is being passed to 'finish', which is then passed to In other words, the tests need to be rewritten. Then the above solution, with I won't get the chance to do that tonight, or probably tomorrow either, so if anyone else would like to do the honors, be my guest. If not, I'll hopefully get to it this week. |
Hmm... I see the issue... Unfortunately, our goal with #389 was to pass the stream as the value so you could do something like: template.render().then(out => out.appendTo(document.body)); |
@patrick-steele-idem Maybe we need to consider having a var result = template.renderSync();
var out = template.render();
out.on('finish', function(result) {});
out.then(function(result) {});
template.render({}, function(err, result) {}); Pretty much everything in the
|
If the point is to get the stream itself when it's done rendering, then doesn't ".on('finish')" already pretty much do that? Both in theory and practice, the point of Promises has always been to handle a single, immutable result (or error) the same way regardless of whether it is known yet or not. In this case, I feel that would be the resulting string. |
In other words, it seems to me that ".render().then()" should behave like ".renderSync()", but allowing for asynchronous values within the template. |
Either way, for a thenable to be passed to the first callback given to ".then()" explicitly defies the core of what a javascript "Promise" is. A separate non-thenable version of the stream like what you described would be the only acceptable way to do that. |
Hm. Somehow didn't notice that ".renderSync()" now returns a stream, too. In that case, this either needs to pass around a non-thenable version of the stream, or not be named ".then". |
That's probably the right thing to do. What are your thoughts on adding a |
What if we were to simply rename |
Fixed in #443. Thanks! |
I finally got around to looking at the newly added
.then
method from #423 , and it turns out that it's nowhere near spec-compliant: attempting to call.catch
causes an error to be thrown ("TypeError: fn is not a function", referring to theundefined
passed as the first argument to.then(fn, fnErr)
), the handlers are called synchronously,and.then
itself ceases to function properly once the stream is finished (subsequent calls return a Promise resolved withundefined
).There are only 3 possible solutions I can think of:1. Let.then
be non-compliant. It will only work if called before the stream is finished, among other things.2. Attach a Promise instance to the stream regardless of whether.then
is ever called or not. The renderer would then always require a native or polyfilledPromise
implementation, even if.then
is never actually used.3. Write a partialPromise
implementation directly into the renderer. I could do this if needed, but it would probably be better to simply require a native or polyfilled implementation.EDIT: It seems I was mistaken about it ceasing to function after 'finish' is called, though it doesn't quite appear to function correctly in the first place.
EDIT 2: I'm actually getting all sorts of weird problems from this code and I'm not entirely sure what's causing most of them. In case someone else wants to take a stab at it, here's a spec-compliant solution, but it caused the test suite to throw an out-of-memory error when I tried it:
The text was updated successfully, but these errors were encountered: