当前位置: 代码迷 >> JavaScript >> 等待跳过以及如何解决?
  详细解决方案

等待跳过以及如何解决?

热度:14   发布时间:2023-06-03 18:14:48.0

我正在使用将一些几何数据流式传输到文件中,但是我无法使用我有限的 Promise 知识来使用它

        const fileStream = streamSaver.createWriteStream('export.obj')
        const writer = fileStream.getWriter()
        const encoder = new TextEncoder

        object.streamExportGeometry(async data => {    //Callback from streamExportGeometry with data to write. Called many times
            console.log("writerQueued");
            await new Promise((resolve, reject) => {
                writer.write(encoder.encode(data)).then(() => { setTimeout(resolve) })
            });
            console.log("writerDone");
        }, onProgress);
        writer.close()

我尝试了许多 await 的变体,但它从不等待 writer.write 完成。 控制台输出如下所示

24x writerQueued 24x writerQueued exported finished 24x writerDone 24x writerDone writerDone

此工具提供了一些,但我不知道如何为我的代码放置承诺

编辑:添加了 streamExportGeometry

 streamExportOBJ(writer, onProgressCallback) {
    var i, j, k, l, x, y, z;

    var vertices = this._vertices ? this._vertices.array : null;

    //Buffer object, to optimize amount of lines per write
    var writeBuffer = {
        _outputBuffer: "",
        _currBuffer: 0,
        _bufferLineLimit: 10000,
        _progress: 0,
        _expectedProgress: 1 + (vertices ? vertices.length / 3 : 0) + (uvs ? uvs.length / 2 : 0) + (normals ? normals.length / 3 : 0) + (indices ? indices.length / 3 : vertices.length / 3),
        writeLine: function (data) {
            this._outputBuffer += data;
            this._currBuffer++;
            if (this._currBuffer >= this._bufferLineLimit)
                this.flush();
        },
        flush: function () {
            if (this._outputBuffer) {
                writer(this._outputBuffer);
                this._outputBuffer = "";
                this._progress += this._currBuffer;
                this._currBuffer = 0;
                onProgressCallback(this._progress / this._expectedProgress * 100);
            }
        }
    }

    writeBuffer.writeLine('o export\n');

    //vertices
    if (vertices !== undefined && vertices && vertices.length >= 3) {
        for (i = 0; i < vertices.length; i += 3) {
            x = vertices[i];
            y = vertices[i + 1];
            z = vertices[i + 2];

            writeBuffer.writeLine('v ' + x + ' ' + y + ' ' + z + '\n');
        }
    }

    //Some more data..

   writeBuffer.flush();
 }

这就是我的建议。 您有streamExportOBJ()尝试同步运行,但它正在调用一个实际上是异步的streamExportOBJ()方法,因此streamExportOBJ()无法真正知道它正在调用的任何异步内容何时完成。 所以,我让你传递给streamExportOBJ()的回调有一个异步接口,然后streamExportOBJ()可以await它。

我不完全确定你想在这里处理错误。 如果在writer.write()发生任何错误,则整个过程将中止,并且错误会渗透回您的顶级,在那里catch(e) {}块将获取它。 你可以在那里制定不同的策略。

async streamExportOBJ(writer, onProgressCallback) {
    var i, j, k, l, x, y, z;

    var vertices = this._vertices ? this._vertices.array : null;

    //Buffer object, to optimize amount of lines per write
    var writeBuffer = {
        _outputBuffer: "",
        _currBuffer: 0,
        _bufferLineLimit: 10000,
        _progress: 0,
        _expectedProgress: 1 + (vertices ? vertices.length / 3 : 0) + (uvs ? uvs.length / 2 : 0) + (normals ? normals.length / 3 : 0) + (indices ? indices.length / 3 : vertices.length / 3),

        writeLine: async function (data) {
            this._outputBuffer += data;
            this._currBuffer++;
            if (this._currBuffer >= this._bufferLineLimit)
                return this.flush();
        },

        flush: async function () {
            if (this._outputBuffer) {
                await writer(this._outputBuffer);
                this._outputBuffer = "";
                this._progress += this._currBuffer;
                this._currBuffer = 0;
                onProgressCallback(this._progress / this._expectedProgress * 100);
            }
        }
    }

    await writeBuffer.writeLine('o export\n');

    //vertices
    if (vertices !== undefined && vertices && vertices.length >= 3) {
        for (i = 0; i < vertices.length; i += 3) {
            x = vertices[i];
            y = vertices[i + 1];
            z = vertices[i + 2];

            await writeBuffer.writeLine('v ' + x + ' ' + y + ' ' + z + '\n');
        }
    }

    //Some more data..

   return writeBuffer.flush();
}

async function someFunction() {
    const fileStream = streamSaver.createWriteStream('export.obj');
    const writer = fileStream.getWriter();
    const encoder = new TextEncoder;

    try {
        await object.streamExportGeometry(async data => {
            console.log("writerQueued");
            await writer.write(encoder.encode(data));
            console.log("writerDone");
        }, onProgress);
    } catch(e) {
        // not sure what you want to do here when there 
        // was an error somewhere in object.streamExportGeometry()
    } finally {
        // always close
        writer.close()
    }
}

仅供参考,如果这是我的代码,我writeBuffer所有writeBuffer功能移动到它自己的类中,并将其从streamExportObj 它似乎是通用的缓冲功能,可以单独实现/测试,然后streamExportOBJ()的逻辑看起来更容易理解和遵循。

  相关解决方案