Javascript fetch API ReadableStream是否与promise一起工作。然后(…)?
我正在尝试使用下载多个文件Javascript fetch API ReadableStream是否与promise一起工作。然后(…)?,javascript,promise,stream,fetch-api,Javascript,Promise,Stream,Fetch 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.ge
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');
});
在下载文件内容之前,代码不会等待。上面的日志是提前打印的。在它运行之后,我看到代码达到了
while (true) {
循环的代码。i、 e.流式传输文件内容的位置
我显然误解了一个基本概念。我如何等待下载文件内容,然后执行其他操作?i、 e.streams如何与promise.then()模型一起工作。发现最简单的解决方案是创建我自己的promise
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');
});
const files=[…];//我的文件对象
常量承诺=[];
for(设i=0;i{
返回新承诺((解决、拒绝)=>{
const reader=response.body.getReader();
const stream=新的ReadableStream({
异步启动(控制器){
while(true){
const{done,value}=wait reader.read();
//当不再需要消耗数据时,中断读取
如果(完成){
打破
}
如果(!file.content){
file.content=值;
}
否则{
file.content+=值;
}
//将下一个数据块排队到我们的目标流中
控制器排队(值);
}
//关闭小溪
controller.close();
读卡器。释放锁();
}
});
});
})
。然后(rs=>新响应(rs))
);
}
返回承诺。全部(承诺)。然后(()=>{
//下载完所有文件后,执行其他操作
log(“下载的所有文件内容”);
});
警告:错误场景也应该被优雅地处理。是的,这就是我希望您的代码的行为方式。当数组中的所有承诺解析时,Promise.all返回。当您返回可读流时,它将解析承诺。ReadableStream中的异步行不是promise.all链的一部分,这里不考虑它。我假设ReadableStream对象将代表我充当promise?我还认为await在封面下是基于承诺的,这意味着它应该与承诺链交错,而不会出现问题?您可以使await和Async成为承诺链的一部分,但在本例中,情况并非如此。定期承诺也是如此。使它们成为链的一部分的唯一方法是在
块中返回它们。不是在一个本身返回承诺的返回对象中。那是在链条之外,这是有道理的。尽管我很难理解如何使用ReadableStream实现这一点。我假设这就是controller.enqueue(value);在寻找一个快速的资源来帮助我时,我发现了一个很酷的npm软件包就是为了这个:碰巧我看到了一篇证实上述内容的文章-
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');
});