我正在尝试使用获取API可读流下载多个文件。
const files = [.....]; // my file objects
const promises = [];
for (let i = 0; i < files.length; i += 1) {
const file = files[i];
promises.push(
fetch(file.uri)
.then(response => {
const reader = response.body.getReader();
return new ReadableStream({
async start(controller) {
while (true) {
const { done, value } = await reader.read();
// When no more data needs to be consumed, break the reading
if (done) {
break;
}
if (!file.content) {
file.content = value;
}
else {
file.content += value;
}
// Enqueue the next data chunk into our target stream
controller.enqueue(value);
}
// Close the stream
controller.close();
reader.releaseLock();
}
});
})
.then(rs => new Response(rs))
);
}
return Promise.all(promises).then(() => {
// do something else once all the files are downloaded
console.log('All file content downloaded');
});这里的想法是文件对象只能有一个URI。然后,此代码将添加一个内容字段。在这之后我还能做点别的。
然而,在实践中,代码序列是不正确的。也就是说,下面的行会彼此紧跟在一起。
return new ReadableStream({...});
console.log('All file content downloaded');在下载文件内容之前,代码不会等待。上面的日志是提前打印的。运行后,我看到代码命中了
while (true) {循环的密码。即文件内容被流的地方。
我显然误解了一个基本概念。我如何等待文件内容被下载,然后,然后做其他的事情呢?例如,流是如何与promise.then()模型工作的。
发布于 2019-03-12 17:48:35
找到最简单的解决办法就是创造我自己的承诺。
const files = [.....]; // my file objects
const promises = [];
for (let i = 0; i < files.length; i += 1) {
const file = files[i];
promises.push(
fetch(file.uri)
.then(response => {
return new Promise((resolve, reject) => {
const reader = response.body.getReader();
const stream = new ReadableStream({
async start(controller) {
while (true) {
const { done, value } = await reader.read();
// When no more data needs to be consumed, break the reading
if (done) {
break;
}
if (!file.content) {
file.content = value;
}
else {
file.content += value;
}
// Enqueue the next data chunk into our target stream
controller.enqueue(value);
}
// Close the stream
controller.close();
reader.releaseLock();
}
});
});
})
.then(rs => new Response(rs))
);
}
return Promise.all(promises).then(() => {
// do something else once all the files are downloaded
console.log('All file content downloaded');
});警告:错误场景也应该被优雅地处理。
https://stackoverflow.com/questions/55110459
复制相似问题