Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/424.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript fetch API ReadableStream是否与promise一起工作。然后(…)?_Javascript_Promise_Stream_Fetch Api - Fatal编程技术网

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');
});