簡體   English   中英

RxJS等待先前的執行完成

[英]RxJS wait for previous execution to finish

好的,所以我是RxJs的新手,我無法弄清楚一些事情。 我需要實現圖像處理,其中用戶一次添加多個圖像,並且對於每個圖像,必須執行以下操作:

  1. 在Web worker中生成圖像縮略圖
  2. 將圖像和縮略圖上傳到服務器

但我不想一次生成所有縮略圖,我希望它們按順序生成。 這是我嘗試過的: https//codesandbox.io/s/funny-mountain-tm0jj?expandandvtools = 1&fontize = 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忍者都想幫助我嗎?

要實現以下目標:

  1. 縮略圖生成應按順序進行,重要的是 =>使用concatMap
  2. 生成縮略圖后應立即上傳
  3. 上傳可以並行順序完成=>使用map

所以最終的代碼可能是

imageObservable
  .pipe(
    // preserve orders and wait for previous observable
    concatMap(generateThumbnail), 

    // map the generate
    map(upload)
  )
  .subscribe();

注意:upload不會等待generateThumbnail promise,因為這應該由concatMap本身處理。

async function upload(image) {
  console.log(`[upload] start ${image.image}`);
  return new Promise(resolve => {
    setTimeout(() => {
      console.log(`[upload] done ${image.image}`);
      resolve();
    }, 1000);
  });
}

您是否只想生成縮略圖是順序的,還是生成第二個縮略圖需要等待上傳第一個縮略圖才能完成?

如果您不想等待上傳,您只需要連接它們:

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做你想要的,我只是用你的創建運算符from你的Promise創建一個Observable ,我認為不需要它。 但是當你使用RxJs時,使用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();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM