Skip to content

Allow async functions to throw #178

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions demos/async.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,16 @@
var req = new XMLHttpRequest();
req.open('GET', href, true);
req.onreadystatechange = function() {
if (req.readyState == 4 && req.status == 200) {
callback(req.responseText);
if (req.readyState == 4) {
if(req.status == 200) {
callback(req.responseText);
} else {
var error = interpreter.createObject(interpreter.ERROR);
interpreter.setProperty(error, 'message',
req.status + req.statusText,
Interpreter.NONENUMERABLE_DESCRIPTOR);
callback(undefined, error);
}
}
};
req.send(null);
Expand Down Expand Up @@ -102,11 +110,20 @@ <h1>JS-Interpreter Async Demo</h1>
will both do nothing, returning <code>true</code> to indicate that the program
still has code to execute.</p>

<p>The callback takes one or two arguments. If called with one, the
supplied value is used as the return value of the asynchronous
call. If called with two, the first is ignored and the second is
used as the value of an exception thrown by the call.</p>

<p>Click <em>Parse</em>, then either click <em>Step</em> repeatedly,
or click <em>Run</em> once. Open your browser's console for errors.</p>

<p><textarea id="code">
alert(getXhr('async.txt'));
try {
alert(getXhr('async.txt'));
} catch(e) {
alert('Failed: ' + e);
}
</textarea><br>
<button onclick="parseButton()">Parse</button>
<button onclick="stepButton()" id="stepButton" disabled="disabled">Step</button>
Expand Down
9 changes: 7 additions & 2 deletions interpreter.js
Original file line number Diff line number Diff line change
Expand Up @@ -3226,8 +3226,13 @@ Interpreter.prototype['stepCallExpression'] = function(stack, state, node) {
state.value = func.nativeFunc.apply(state.funcThis_, state.arguments_);
} else if (func.asyncFunc) {
var thisInterpreter = this;
var callback = function(value) {
state.value = value;
var callback = function(value, exception) {
if (arguments.length <= 1) {
state.value = value;
} else {
thisInterpreter.unwind(Interpreter.Completion.THROW,
exception, undefined);
}
thisInterpreter.paused_ = false;
};
// Force the argument lengths to match, then append the callback.
Expand Down