好,所以我是RxJ的新手,我不知道有什么事情。 我需要实现图像处理,在该图像处理中,用户一次添加多个图像,并且对于每个图像,必须执行以下操作:
但是我不希望一次生成所有缩略图,而是希望它们依次生成。这是我尝试的方法:https://codesandbox.io/s/funny-mountain-tm0jj?expanddevtools=1&fontsize=14
我还将代码粘贴到这里:
import { of } from "rxjs";
import { map } from "rxjs/operators";
const imageObservable = of(1, 2, 3, 4, 5);
function generateThumbnail(image) {
console.log(`Generating thumbnail ${image}`);
return new Promise(resolve => {
setTimeout(() => {
console.log(`Finished generating thumbnail ${image}`);
resolve({
image,
thumbnail: `This is a thumbnail of image ${image}`
});
}, 1500);
});
}
async function upload(imagePromise) {
const image = await imagePromise;
console.log("Uploading", image);
return new Promise(resolve => {
setTimeout(() => {
console.log("Finished uploading", image);
resolve();
}, 1500);
});
}
imageObservable.pipe(map(generateThumbnail)).subscribe(upload);
我希望RxJS等待上一个generateThumbnail
才能执行当前调用(这就是为什么它返回一个promise对象的原因),并且还要等待上一个upload
以便执行当前调用(因此upload
也返回了promise)。我不知道如何实现这一目标。任何RxJS忍者都想帮助我吗?
答案 0 :(得分:2)
要实现以下目标:
所以最终的代码可能是
imageObservable
.pipe(
// preserve orders and wait for previous observable
concatMap(generateThumbnail),
// map the generate
map(upload)
)
.subscribe();
注意:上传不会等待generateThumbnail承诺,因为这应该由concatMap本身处理。
async function upload(image) {
console.log(`[upload] start ${image.image}`);
return new Promise(resolve => {
setTimeout(() => {
console.log(`[upload] done ${image.image}`);
resolve();
}, 1000);
});
}
答案 1 :(得分:1)
您只希望生成缩略图是连续的,还是要生成第二个缩略图就需要等待第一个缩略图的上传完成?
如果您不想等待上传,只需将它们连在一起即可:
import { of, from, } from 'rxjs';
import { concatMap } from 'rxjs/operators';
const imageObservable = of(1, 2, 3, 4, 5);
function generateThumbnail(image) {
console.log(`Generating thumbnail ${image}`);
return new Promise(resolve => {
setTimeout(() => {
console.log(`Finished generating thumbnail ${image}`);
resolve({
image,
thumbnail: `This is a thumbnail of image ${image}`
});
}, 1500);
});
}
async function upload(imagePromise) {
const image = await imagePromise;
console.log('Uploading', image);
return new Promise(resolve => {
setTimeout(() => {
console.log('Finished uploading', image);
resolve();
}, 1500);
});
}
// imageObservable.pipe(map(generateThumbnail)).subscribe(upload);
imageObservable.pipe(concatMap(image => from(generateThumbnail(image)))).subscribe();
concatMap可以满足您的需求,我只是使用Observable
创新运算符从您的Promise
中提取了一个from
,我认为这不是必需的。但是,使用RxJ时,通常更容易使用Observables
而不是Promises
。
function generateThumbnail(image): Observable<any> {
console.log(`Generating thumbnail ${image}`);
return from(
new Promise(resolve => {
setTimeout(() => {
console.log(`Finished generating thumbnail ${image}`);
resolve({
image,
thumbnail: `This is a thumbnail of image ${image}`
});
}, 1500);
})
);
}
编辑: 你可以试试吗?
imageObservable
.pipe(
concatMap(image => generateThumbnail(image)),
concatMap(image => upload(image))
)
.subscribe();