我正在尝试使用Emscripten编写软件,使其可以在浏览器中运行,也可以在其他体系结构(例如Android,PC独立应用)上运行。
软件结构如下:
main_program_loop() {
if (gui.button_clicked()) {
run_async(some_complex_action, gui.text_field.to_string())
}
if (some_complex_action_has_finished())
{
make_use_of(get_result_from_complex_action());
}
}
some_complex_action(string_argument)
{
some_object = read_local(string_argument);
interm_res = simple_computation(some_object);
other_object = expensive_computation(interm_res);
send_remote(some_object.member_var, other_object);
return other_object.member_var;
}
让我们调用main_program_loop
GUI或前端,some_complex_action
中间层,以及read_local
,send_remode
和expensive_computation
后端或下层。
现在,前端和后端将是特定于体系结构的(例如,对于Javascript read_local
可以使用IndexDB
,send_remote
可以使用fetch
),
但是中间层应占代码的50%以上(这就是为什么我不想用两种不同的语言编写两次,而是用C语言编写一次并将其转换为Javascript的原因,对于Android,我将使用JNI )。
出现问题是因为Javascript中最低层的功能(fetch
等)异步运行(返回承诺或需要回调)。
我尝试的一种方法是使用promise并通过中间层发送ID
var promises = {};
var last_id = 0;
handle_click() {
var id = Module.ccall('some_complex_action', 'number', ['string'], [text_field.value]);
promises[id].then((result) => make_us_of(result));
}
recv_remote: function(str) {
promises[last_id] = fetch(get_url(str)).then((response) => response.arrayBuffer());
last_id += 1;
return last_id - 1;
}
它适用于简单的情况
some_complex_action(char *str)
{
return recv_remote(str);
}
但是在实际情况下,这似乎变得非常复杂,也许不可能。 (我尝试了一些方法,在此方法中,我给每个函数一个状态,并且每次后端函数完成时,都会调用该函数并提升其状态,但是代码开始变得像地狱一样复杂。)要比较,如果我要从C或Java调用some_complex_action
,我只是在与GUI线程不同的线程中调用它,并且在该线程中,所有事情都会同步发生。
我希望我可以从异步函数中调用some_complex_action
并将await
放入recv_remote
内,但是由于这种原因,我只能直接在异步函数中等待,而不能在某些函数中等待下线。因此,这个想法也不可行。
理想情况下,如果我能以某种方式停止执行Emscripten中间代码,直到后端函数完成,然后从后端函数返回结果,然后继续执行代码。
有人使用过Emterpreter,可以想象它可以帮助我实现自己的目标吗?
有什么想法我能做什么?