Skip to content
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