-
Notifications
You must be signed in to change notification settings - Fork 354
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
API to append call to arbitrary function #147
Comments
Works for me: > myInterpreter.appendCode('(function(){return 42;})();');
> myInterpreter.run();
> myInterpreter.value;
=> 42 |
I appreciate you looking at this. Let me be more specific. I'm trying to make an external API that wraps setInterval. I have code like the following in my init function:
This works if the callback function already exists:
But not if an unnamed function is used:
So I'm asking for a way to save a reference to an unnamed function that can be called later on. Perhaps there is a better way to achieve the same result? |
Ahh. Implementing asynchronous functions is a bit tricky. The most straight-forward approach would be to use the technique discussed in the documentation in the paragraph beginning "Asynchronous API functions…", which will give you a synchronous wrapper for an async function. (You'll still need to make sure that someone calls If you want the API to appear asynchronous from the point of view of the user code (like But if you don't mind the array of timer callbacks being user-manipulable, you could store the callback in a global pseudoArray (say, |
This is exactly what I'm trying to do. I hadn't thought of saving the callback within the interpreter instance. The part that is still unclear to me is how would a native function save the callback to a pseudoArray? A more elegant solution would be much appreciated, too. |
Hi, I know this is an old thread, but I'm also interested in calling an interpreted callback. After having read the various related issues here, I thought of a simpler solution which seems to work and seems close to what is done in the browser (as far as I can understand): When a callback needs to be executed, simply append its code to the interpreter and continue the execution if it was stopped. Here's my interpreter's simplified code: // Whether the interpreter is stopped (did not yet run, or reached the end).
let stopped = true;
// Execute a step at a time until the end is reached.
function step(interpreter) {
if (interpreter.step()) {
stopped = false;
window.setTimeout(() => {
step(interpreter);
}, 0);
} else {
stopped = true;
}
}
// Run code
export function run(code, init) {
const interpreter = new Interpreter(code, init);
step(interpreter);
}
// Append code and continue execution if stopped
export function append(code, interpreter) {
interpreter.appendCode(code);
if (stopped) {
step(interpreter);
}
} And here's an example usage: // Keep track of listeners to be able to remove them.
const listeners = [];
// Define 'addEventListener' property.
interpreter.setProperty(
globalObject,
"addEventListener",
interpreter.createNativeFunction(function (id, type, callback) {
const el = document.getElementById(id);
// Wrap the callback.
const wrapper = function () {
append(callback, interpreter);
};
// Add the event listener
el.addEventListener(type, wrapper);
// Add to the list of listeners
listeners.push({
el,
type,
callback: wrapper,
});
return true;
})
); Is this a bad thing to do? Can it have bad side effects? [moved here from #153 as that one is closed] |
There does not appear to be a way to call an unnamed function from an external API. If the function to be called was declared ahead of time, it has a name. So the external API can append JavaScript to call it by name. It would be nice if there was a similar way to call unnamed functions.
Unnamed function example:
externalAPI(function(){
alert('external API is finished');
});
The text was updated successfully, but these errors were encountered: