【发布时间】:2021-05-15 12:55:22
【问题描述】:
我想通过等待用户在 HTML input 字段中键入一些文本,然后继续进行其余的 WASI 调用,从 WASI API 实现 fd_read。即,类似于:
fd_read = (fd, iovs, iovsLen, nread) => {
// only care about 'stdin'
if(fd !== STDIN)
return WASI_ERRNO_BADF;
const encoder = new TextEncoder();
const view = new DataView(memory.buffer);
view.setUint32(nread, 0, true);
// create a UInt8Array for each buffer
const buffers = Array.from({ length: iovsLen }, (_, i) => {
const ptr = iovs + i * 8;
const buf = view.getUint32(ptr, true);
const bufLen = view.getUint32(ptr + 4, true);
return new Uint8Array(memory.buffer, buf, bufLen);
});
// get input for each buffer
buffers.forEach(buf => {
const input = waitForUserInput();
buf.set(encoder.encode(input));
view.setUint32(nread, view.getUint32(nread, true) + input.length, true);
});
return WASI_ESUCCESS;
}
如果提供了变量input,则该实现有效。例如,设置const input = "1\n" 将该字符串传递给我的C 程序中的scanf 调用,它读取的值是1。
但是,在等待提供输入时,我正在努力“停止”JavaScript 执行。我知道 JavaScript 是事件驱动的,不能在传统意义上“暂停”,但是尝试将输入作为回调/承诺提供函数仍然执行的问题,导致没有任何东西传递给 stdin :
buffers.forEach(buf => {
let input;
waitForUserInput().then(value => {
input = value;
});
buf.set(encoder.encode(input));
view.setUint32(nread, view.getUint32(nread, true) + input.length, true);
});
由于输入仍在等待设置,缓冲区中没有任何内容被编码,stdin 只是读取0。
有没有办法等待async/await 的输入,或者使用setTimeout 的“hack-y”解决方案?我知道window.Prompt() 会停止执行,但我希望输入成为页面的一部分。寻找原生 JavaScript 解决方案。
【问题讨论】:
标签: javascript c webassembly