webassembly/proxy_js: Promote Python thenable to a Promise.
Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
@@ -89,7 +89,22 @@ function proxy_call_python(target, argumentsList) {
|
|||||||
if (argumentsList.length > 0) {
|
if (argumentsList.length > 0) {
|
||||||
Module._free(args);
|
Module._free(args);
|
||||||
}
|
}
|
||||||
return proxy_convert_mp_to_js_obj_jsside_with_free(value);
|
const ret = proxy_convert_mp_to_js_obj_jsside_with_free(value);
|
||||||
|
if (ret instanceof PyProxyThenable) {
|
||||||
|
// In Python when an async function is called it creates the
|
||||||
|
// corresponding "generator", which must then be executed at
|
||||||
|
// the top level by an asyncio-like scheduler. In JavaScript
|
||||||
|
// the semantics for async functions is that they are started
|
||||||
|
// immediately (their non-async prefix code is executed immediately)
|
||||||
|
// and only if they await do they return a Promise to delay the
|
||||||
|
// execution of the remainder of the function.
|
||||||
|
//
|
||||||
|
// Emulate the JavaScript behaviour here by resolving the Python
|
||||||
|
// async function. We assume that the caller who gets this
|
||||||
|
// return is JavaScript.
|
||||||
|
return Promise.resolve(ret);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
function proxy_convert_js_to_mp_obj_jsside(js_obj, out) {
|
function proxy_convert_js_to_mp_obj_jsside(js_obj, out) {
|
||||||
|
|||||||
31
tests/ports/webassembly/fun_py_callback_js.mjs
Normal file
31
tests/ports/webassembly/fun_py_callback_js.mjs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
// Test using Python functions as JS callbacks.
|
||||||
|
|
||||||
|
const mp = await (await import(process.argv[2])).loadMicroPython();
|
||||||
|
|
||||||
|
globalThis.asyncTimeout = (ms) =>
|
||||||
|
new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
|
|
||||||
|
mp.runPython(`
|
||||||
|
import js
|
||||||
|
|
||||||
|
def f0():
|
||||||
|
print("f0 run")
|
||||||
|
|
||||||
|
async def f1():
|
||||||
|
print("f1 run")
|
||||||
|
|
||||||
|
async def f2():
|
||||||
|
print("f2 start")
|
||||||
|
await js.asyncTimeout(0)
|
||||||
|
print("f2 end")
|
||||||
|
|
||||||
|
async def f3():
|
||||||
|
print("f3 start")
|
||||||
|
await f2()
|
||||||
|
print("f3 end")
|
||||||
|
|
||||||
|
js.setTimeout(f0, 0)
|
||||||
|
js.setTimeout(f1, 50)
|
||||||
|
js.setTimeout(f2, 100)
|
||||||
|
js.setTimeout(f3, 150)
|
||||||
|
`);
|
||||||
8
tests/ports/webassembly/fun_py_callback_js.mjs.exp
Normal file
8
tests/ports/webassembly/fun_py_callback_js.mjs.exp
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
f0 run
|
||||||
|
f1 run
|
||||||
|
f2 start
|
||||||
|
f2 end
|
||||||
|
f3 start
|
||||||
|
f2 start
|
||||||
|
f2 end
|
||||||
|
f3 end
|
||||||
Reference in New Issue
Block a user