2016-12-07 7 views
0

私はRedux Thunkから来ているので、私はRedux Sagaの新しいブランドです。私は単純なtakeEveryコールをいくつか実装することができましたが、私はより複雑なソリューションに苦労しています。あなたが正しい方向に向けるかどうか疑問に思います。Redux Saga - 複雑な制御フロー

私はRedux Persistを使用して選択した注文をオフラインで保存し、接続したときにそれらを定期的にサーバーに同期させるウェアハウスアプリケーションを作成しています。私は以下の私のReduxの状態のサンプルを添付した

を選んで確認し

  1. 更新量
  2. を選んだ:それらを同期させるために、私は私が独立して行う必要がありますし、ために、2つのAPI呼び出しを持っています。 ordersToSyncを見ると、最初に最初のメソッドでPickedQuantityとPickingListDetailIdを(個別に)ポストし、2番目のメソッドを使ってPickListIdでピックを確定する必要があります。

    これまでのところ、私はes6ジェネレータを作成して、データが同期しているかどうか、またはエラーがあるかどうかに関わらず、いくつかのフラグを使って接続を確認する動作をシミュレートしました。私が添付したコードをコピーして貼り付けてhttps://stephengrider.github.io/JSPlaygrounds/に入れ、コンソールをチェックすると、目的の結果が表示されます。

    私はこれをRedux Sagaに適用するというコンセプトに苦労しているので、このプロセスはノンブロッキングコールとしてバックグラウンドで機能します。誰かが正しい方向に私を向けるのを助けることができますか?

    事前に感謝します。これについてどのように

    // Example Sync Queue (Persisted Redux state) 
        const ordersToSync = [ 
         { 
         "pickingListId": 2362, 
         "itemsPicked": [ 
          { 
          "PickingListDetailId": 3115, 
          "ProductId": 3387, 
          "ProductSKU": "123XP", 
          "ProductTitle": "Frameset", 
          "PickQuantity": 2, 
          "PickedQuantity": 2 
          }, 
          { 
          "PickingListDetailId": 3114, 
          "ProductId": 3386, 
          "ProductSKU": "123XP", 
          "ProductTitle": "Frameset", 
          "PickQuantity": 3, 
          "PickedQuantity": 1 
          }, 
          { 
          "PickingListDetailId": 3116, 
          "ProductId": 3385, 
          "ProductSKU": "123XP", 
          "ProductTitle": "Frameset", 
          "PickQuantity": 4, 
          "PickedQuantity": 4 
          } 
         ] 
         }, 
         { 
         "pickingListId": 2374, 
         "itemsPicked": [ 
          { 
          "PickingListDetailId": 3105, 
          "ProductId": 3088, 
          "ProductSKU": "123XP", 
          "ProductTitle": "Frameset", 
          "PickQuantity": 1, 
          "PickedQuantity": 1 
          } 
         ] 
         }, 
         { 
         "pickingListId": 2322, 
         "itemsPicked": [ 
          { 
          "PickingListDetailId": 3101, 
          "ProductId": 3187, 
          "ProductSKU": "123XP", 
          "ProductTitle": "Frameset", 
          "PickQuantity": 2, 
          "PickedQuantity": 2 
          }, 
          { 
          "PickingListDetailId": 3118, 
          "ProductId": 3286, 
          "ProductSKU": "123XP", 
          "ProductTitle": "Frameset", 
          "PickQuantity": 3, 
          "PickedQuantity": 1 
          }, 
          { 
          "PickingListDetailId": 3125, 
          "ProductId": 3325, 
          "ProductSKU": "123XP", 
          "ProductTitle": "Frameset", 
          "PickQuantity": 4, 
          "PickedQuantity": 4 
          } 
         ] 
         }, 
        ]; 
    
        // Represents Redux Reducer 
        const error = false; // Flip if error comes back from axios request 
        const syncing = false; // Flip whilst axios request does its thing 
        const connectionType = 'WIFI'; // Toggled by 
    
        // ES6 generator for dispatching sync actions 
        function* OrderIterator() { 
         // If we have a suitable connection (NetInfo connection type) 
         if (connectionType === 'WIFI') { 
         // If we are not already syncing some data 
         // And we have no errors 
         if (!syncing && !error) { 
          for (const order of ordersToSync) { 
          for (const item of order.itemsPicked) { 
           // Dispatch updatePickQuantityAction 
           // 1. Flip the syncing state to true UPDATE_PICK_QUANTITY_START 
           // 2. If there is an error stop everything and flip the error state to true UPDATE_PICK_QUANTITY_FAIL 
           // 3. If everything goes well with the request, flip the syncing state to false and carry on UPDATE_PICK_QUANTITY_SUCCESS 
           yield console.log(`this.props.updatePickQuantityAction(${item.PickedQuantity}, ${item.PickingListDetailId});`); 
          } 
          if(!syncing && !error) { 
           // Dispatch confirmPickAction 
           // 1. Flip the syncing state to true CONFIRM_PICK_START 
           // 2. If there is an error stop everything and flip the error state to true CONFIRM_PICK_FAIL 
           // 3. If everything goes well with the request, flip the syncing state to false and carry on CONFIRM_PICK_SUCCESS 
           yield console.log(`this.props.confirmPickAction(${order.pickingListId});`); 
          } 
          // Dispatch removeConfirmedPickAction 
          // This will remove the pick from sync queue (Redux state not API) after it has been confirmed 
          console.log(`this.props.removeConfirmedPickAction();`); 
          } 
         } 
         } 
        } 
    
        const SyncOrders = OrderIterator(); 
    
        for (const item of SyncOrders) { 
         item; 
        } 
    

答えて

0

export const ordersToSync = state => state.ordersToSync; 
export const getLastSavedItemId = state => state.lastSavedItemId; 
export const getItemFailedOnConfirm = state => state.itemFailedOnCofirm; 

export function *syncDataIdea() { 
    const ordersToSync = yield select(ordersToSync); 
    for (const order of ordersToSync) { 
    for (const item of order.itemsPicked) { 
     yield call(updatePickQuantityAction, item.PickedQuantity); 
    } 
    yield call(confirmPickAction, order.pickingListId); 
    yield call(removeConfirmedPickAction, order.pickingListId); 
    } 
} 

export function *syncData() { 
    const ordersToSync = yield select(ordersToSync); 
    for (const order of ordersToSync) { 
    const itemFailedOnConfirm = yield select(getItemFailedOnConfirm); 
    if (itemFailedOnConfirm === null) { 
     const lastSavedItemId = yield select(getLastSavedItemId); 
     for (const item of order.itemsPicked) { 
     const itemId = item.PickedQuantity.PickingListDetailId; 
     try { 
      if (lastSavedItemId !== null 
      && lastSavedItemId !== itemId) { 
      continue; 
      } 
      yield call(updatePickQuantityAction, item.PickedQuantity); 
      yield put({type: 'SET_LAST_SAVED_ITEM', getLastSavedItemId: null}); 
     } 
     catch (error) { 
      yield put({ 
      type: 'SET_LAST_SAVED_ITEM', getLastSavedItemId: itemId 
      }); 
     } 
     finally { 
      if (yield cancelled()) { 
      yield put({ 
       type: 'SET_LAST_SAVED_ITEM', getLastSavedItemId: itemId 
      }); 
      } 
     } 
     } 
    } 
    try { 
     yield call(confirmPickAction, order.pickingListId); 
     yield put({type: 'ITEM_FAILED_ON_CONFIRM', pickingListId: null}); 
    } 
    catch (error) { 
     yield put({type: 'ITEM_FAILED_ON_CONFIRM', pickingListId: order.pickingListId}); 
    } 
    finally { 
     if (yield cancelled()) { 
     yield put({type: 'ITEM_FAILED_ON_CONFIRM', pickingListId: order.pickingListId}); 
     } 
    } 
    yield call(removeConfirmedPickAction, order.pickingListId); 
    } 
} 

function* main() { 
    while (yield take('WIFI_ON')) { 
    const syncDataTask = yield fork(syncData); 
    yield take('WIFI_OFF'); 
    yield cancel(syncDataTask); 
    } 
} 

注意してください、私はまた、redux-sagaに非常に新しいです。私はあなたを見てみることをお勧めしますhttps://redux-saga.github.io/redux-saga/docs/advanced/TaskCancellation.html