首页 > 解决方案 > 为什么我的 for await 循环在异步迭代器中无限循环?

问题描述

我正在使用 s3 aws-sdk 来获取多个文件中的多个记录。s3.selectObjectContent 调用返回一个读取流。我使用 .map 返回这些读取流的列表,然后等待所有对该列表的承诺,以便获取可读流的列表。然后我尝试 for await 循环遍历所有流以获取块并作为一个块列表返回,以便生成所有事件/块的单个读取流。

现在,这 for await 在 .map 内部起作用,但是一旦我在地图返回后在外部执行它,它就会无限循环。

async function* concatenateStreamsOrdered(streams) {
  for (const stream of streams) {
    for await (const chunk of stream) {
      yield chunk
    }
  }
}

async function getS3SelectObjectsStreams(bucket, sourceKeys, expression) {
  let readStreamPromises = 
    sourceKeys.map(
      async sourceKey => {
        let selectParameters = {
          Bucket: bucket,
          Key: sourceKey,
          Expression: expression, 
          ExpressionType: 'SQL', 
          InputSerialization: { 
            JSON: {
              Type: 'DOCUMENT'
            }
          },
          OutputSerialization: {
            JSON: {
              RecordDelimiter: ','
            }
          }
        };
        let result = await s3.selectObjectContent(selectParameters).promise();
        // for await (const event of result.Payload) {}
        return result.Payload;
      }
    );
  let readStreams = await Promise.all(readStreamPromises);
  const iterableStreams = await concatenateStreamsOrdered(readStreams);
  return stream.Readable.from(iterableStreams);
}

因此,当我取消注释上面评论的 for await 时,它可以立即响应没有问题。当我按原样注释掉它时,concatenateStreamsOrdered 函数中的 for await 将永远循环。

读取流(result.Payload)是否以某种方式分离?如何让它在 concatenateStreamsOrdered 函数而不是 map 函数中工作?

标签: javascriptnode.jsaws-sdk-jsnode-streams

解决方案


推荐阅读