Это то, что я бы предложил.У вас есть 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
в свой собственный класс и вывел бы их из streamExportObj
.Похоже, что это общая функция буферизации и может быть реализована / протестирована отдельно, и тогда логика streamExportOBJ()
будет проще понять и следовать.