В общем, вы обычно хотите избежать вложения одного выражения вычисления в другое, потому что это может сбить с толку то, что относится к чему. В частности, здесь вы намереваетесь интерпретировать выражение let!
как async { let! foo = AsyncFoo() }
, но это выражение вычисления seq { }
интерпретирует let!
.
Я бы порекомендовал разделить seq { }
на его собственную функцию, а также с зацикленной частью асинхронного режима. Остальная часть функции listObjects
не обязательно должна быть асинхронной,
let keysFromPartialResponse response = seq {
for entry in response.S3Objects do
yield entry.Key
}
let doRequest request resultSoFar = async {
let! response = client.ListObjectsV2Async(request) |> Async.AwaitTask
request.ContinuationToken <- response.NextContinuationToken
let result = Seq.append resultSoFar (keysFromPartialResponse response)
if request.IsTruncated then
return! doRequest request result // This is the loop step
else
return result
}
let listObjects bucketName = async {
use client = new AmazonS3Client(RegionEndpoint.USEast2)
let request = new ListObjectsRequest(BucketName = bucketName, MaxKeys = 10)
return! doRequest request Seq.empty
}
Возможно, есть лучшее решение, использующее AsyncSeq , но я оставлю это как упражнение для читателя.
Обратите внимание, что есть одна проблема с вашим кодом F #, которая все еще существует в моем коде, а именно, что последовательности являются ленивыми и фактически не будут выполнять код seq { ... }
, пока они не будут оценены. И поскольку вы использовали use
, как только объект client
выйдет из области видимости (т. Е. Когда вернется асинхронный режим), экземпляр AmazonS3Client
будет удален. Таким образом, к тому времени, когда вы оцените последовательность (которая будет оценивать response.S3Objects
), клиент больше не будет действительным. Если это означает, что оценка response.S3Objects
не удастся, вам придется преобразовать этот код, чтобы использовать списки вместо seqs. Должно быть достаточно просто, поэтому я оставлю это вам, но дайте мне знать, если у вас есть проблемы с этим.