亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在 RxJS/redux-observable 和 redux-saga 中對操作進行排序?

如何在 RxJS/redux-observable 和 redux-saga 中對操作進行排序?

九州編程 2022-06-05 15:56:14
我已經開始深入學習 RxJs,其中一個原因是要掌握redux-observable副作用方法,但我發現 sagas 更方便和“聲明性”。我已經學過merge/flat/concat/switchMap運算符,但它并沒有幫助我弄清楚如何在 rxjs 中對事物進行排序。這是我所說的“排序”的一個例子,在 Timer 應用程序的實例上,可以在一段時間后安排啟動,實現redux-saga:export function* timerSaga() {  while (true) {    yield take('START');    const { startDelay } = yield select(); // scheduled delay    const [cancelled] = yield race([      take('CANCEL_START'),      delay(startDelay)    ]);    if (!cancelled) {      yield race([        call(function*() {           while (true) {             yield delay(10);             yield put({ type: 'TICK' });           }        }),        take(['STOP', 'RESET']      ]);    }  }}我發現這個例子在邏輯上非常一致和清晰。我不知道如何用 redux-observable 來實現它。請簡單地給我一些代碼,這些代碼可以重現相同的邏輯但帶有rxjs運算符。
查看完整描述

2 回答

?
侃侃爾雅

TA貢獻1801條經驗 獲得超16個贊

在 sagas(生成器)和 epics(observables)之間,重要的是要改變您對事件如何到達您的代碼的看法。


生成器滿足迭代器和可迭代協議,這涉及從源中提取 值/事件(在本例中為 Redux 操作),并在這些事件到達之前阻止執行。


Observables 是推而不是拉。我們描述和命名我們感興趣的事件流,然后訂閱它們。沒有阻塞調用,因為我們所有的代碼都是由事件發生時觸發的。


此代碼復制了 saga 示例中的行為。


import { interval, timer } from 'rxjs';

import { withLatestFrom, mapTo, exhaustMap, takeUntil } from 'rxjs/operators';

import { ofType } from 'redux-observable';


const myEpic = (action$, state$) => {

  // A stream of all the "cancel start" actions

  const cancelStart$ = action$.pipe(ofType('CANCEL_START'));


  // This observable will emit delayed start events that are not cancelled.

  const delayedCancellableStarts$ = action$.pipe(

    // When a start action occurs...

    ofType('START'), 


    // Grab the latest start delay value from state...

    withLatestFrom(state$, (_, { startDelay }) => startDelay),


    exhaustMap(

      // ...and emit an event after our delay, unless our cancel stream

      // emits first, then do nothing until the next start event arrives.


      // exhaustMap means we ignore all other start events while we handle

      // this one.

      (startDelay) => timer(startDelay).pipe(takeUntil(cancelStart$))

    )

  );


  // On subscribe, emit a tick action every 10ms

  const tick$ = interval(10).pipe(mapTo({ type: 'TICK' }));


  // On subscribe, emit only STOP or RESET actions

  const stopTick$ = action$.pipe(ofType('STOP', 'RESET'));


  // When a start event arrives, start ticking until we get a message to

  // stop. Ignore all start events until we stop ticking.

  return delayedCancellableStarts$.pipe(

    exhaustMap(() => tick$.pipe(takeUntil(stopTick$)))

  );

};

重要的是,即使我們正在創建和命名這些可觀察的流,它們的行為也是惰性的——在訂閱之前它們都不會被“激活”,當你向redux-observable中間件提供這個史詩功能時就會發生這種情況。


查看完整回答
反對 回復 2022-06-05
?
絕地無雙

TA貢獻1946條經驗 獲得超4個贊

我假設take()返回一個可觀察的,沒有測試代碼。它可能可以轉換為如下所示的 rx 時尚。


這里的關鍵是repeat()和takeUntil()


// outter condition for starting ticker

forkJoin(take('START'), select())

    .pipe(

        switchMap(([, startDelay]) =>

            // inner looping ticker

            timer(10).pipe(switchMap(_ => put({type: 'TICK'})), repeat(),

                takeUntil(race(

                    take('CANCEL_START'),

                    delay(startDelay)

                ))

            )

            /////////////////////

        )

    )


查看完整回答
反對 回復 2022-06-05
  • 2 回答
  • 0 關注
  • 110 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號