我有一段代码,它使用并返回一个承诺。但是,我想将其转换为可观察的。请指教。
原始代码:
export const uploadMultipleFilesToAzure = (
uploadData: Omit<UploadMultipleToAzure, 'id'>[],
handleProgress: (
loadedBytes: number,
fileData: UploadMultipleToAzure['fileData'],
uploadId: Upload['id']
) => void,
individualCallback: Function
): Promise<BlockBlobUploadHeaders[]> => {
const PIPELINE: Pipeline = newPipeline(new AnonymousCredential(), {
retryOptions: { maxTries: 4 }, // Retry options
keepAliveOptions: {
// Keep alive is enabled by default, disable keep alive by setting false
enable: false,
},
});
const promises: Promise<BlobUploadCommonResponse>[] = [];
forEach(uploadData, (uploadItem) => {
let blockBlobClient: BlockBlobClient = new BlockBlobClient(
uploadItem.BlobURL,
PIPELINE
);
promises.push(
(
blockBlobClient.uploadData(uploadItem.fileData as Blob, {
blockSize:
(uploadItem.fileData as Blob).size > 1024 * 1024 * 32
? 1024 * 1024 * 4
: 1024 * 512,
maxSingleShotSize: 1024 * 512,
concurrency: 20, // 20 concurrency,
onProgress: (ev: TransferProgressEvent) =>
handleProgress(
ev.loadedBytes / (uploadItem.fileData as Blob).size,
uploadItem.fileData,
uploadItem.id
),
}) as any
).then(() => {
individualCallback(uploadItem);
})
);
});
return Promise.all(promises);
};
答案 0 :(得分:0)
在我看来,这就像一个简单的 forkJoin 情况。
简化,你有:
const uploadMultipleFilesToAzure = (uploads: any[]) =>
forkJoin(uploads.map(upload =>
upload.somethingReturningPromise(prms)
);
这只是将 Promises.all 替换为 forkJoin。 forkJoin 可以将 promise 作为输入,并会发出带有结果数组的单个事件。
如果你有内部的“then”,它就会变成一个 xMap - 让我们假设 mergeMap。您现在需要 from() 将 promise 转换为 observable:
const uploadMultipleFilesToAzure = (uploads: any[]) =>
forkJoin(uploads.map(upload =>
from(upload.somethingReturningPromise(prms)).pipe(
mergeMap( ()=> individualCallback(uploadItem);
)
);
最后,如果您使用 forkJoin 或 from() ,那么在调用此函数(以创建 observable)时将调用 promise,而不是在订阅 observable 时调用。出于这个原因,通常最好使用 defer() 代替:
const uploadMultipleFilesToAzure = (uploads: any[]) =>
forkJoin(uploads.map(upload =>
defer(() => upload.somethingReturningPromise(prms)).pipe(
mergeMap( ()=> individualCallback(uploadItem);
)
);