问题描述
我正在使用将一些几何数据流式传输到文件中,但是我无法使用我有限的 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();
}
1楼
jfriend00
1
已采纳
2019-02-13 00:46:07
这就是我的建议。
您有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()
的逻辑看起来更容易理解和遵循。