首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >fetch-API ReadableStream与promise.then(.)一起工作吗?

fetch-API ReadableStream与promise.then(.)一起工作吗?
EN

Stack Overflow用户
提问于 2019-03-11 21:10:55
回答 1查看 1.2K关注 0票数 1

我正在尝试使用获取API可读流下载多个文件。

代码语言:javascript
复制
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。然后,此代码将添加一个内容字段。在这之后我还能做点别的。

然而,在实践中,代码序列是不正确的。也就是说,下面的行会彼此紧跟在一起。

代码语言:javascript
复制
return new ReadableStream({...});
console.log('All file content downloaded');

在下载文件内容之前,代码不会等待。上面的日志是提前打印的。运行后,我看到代码命中了

代码语言:javascript
复制
while (true) {

循环的密码。即文件内容被流的地方。

我显然误解了一个基本概念。我如何等待文件内容被下载,然后,然后做其他的事情呢?例如,流是如何与promise.then()模型工作的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-12 17:48:35

找到最简单的解决办法就是创造我自己的承诺。

代码语言:javascript
复制
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');
});

警告:错误场景也应该被优雅地处理。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55110459

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档