2017-07-17 67 views
0

我使用阿波羅客戶端進行查詢和突變我GraphQL服務器功能。由於Apollo有它自己的錯誤處理,實現takeUntil函數來取消我的查詢調用和我的變化要困難得多。使用RxJs takeUntil()與阿波羅的客戶端

使用阿波羅,這裏是我的突變是什麼樣子:

export const languageTimeZoneEpic = (action$) => { 
    return action$.ofType(CHANGE_LANGUAGE) 
    .mergeMap(action => client.mutate({ 
     mutation: languageMutation, 
     variables: { id: action.id, language: action.selected_language } 
    }).then(result => changeLanguageFulfilled(result)) 
     .catch(error => changeLanguageError(error)) 
); 
}; 

我的突變沒有問題提出,如果有一個錯誤,它抓住了它。 這裏的問題是,如果我像下面的例子中添加takeUntil()函數,我的函數根本無法工作。

export const languageTimeZoneEpic = (action$) => { 
    return action$.ofType(CHANGE_LANGUAGE) 
    .mergeMap(action => client.mutate({ 
     mutation: languageMutation, 
     variables: { id: action.id, language: action.selected_language } 
    }).then(result => changeLanguageFulfilled(result)) 
     .catch(error => changeLanguageError(error)) 
).takeUntil("END_LANGUAGE"); 
}; 

我想知道是否有一種方法能夠使用takeUntil()功能,即使我使用有它自己的錯誤處理的客戶端。

*如果我派遣另一個動作前的突變是完整的takeUntil(這裏)將被調用。

謝謝

回答

1

takeUntil不接受一個字符串作爲它的參數。相反,它期望它將訂閱的Observable,使用第一個next'd值作爲信號。

終極版,可觀察到的是99.9%只RxJS,所以所有的運營商一無所知終極版/行動除了ofType這是唯一的運營商Redux的可觀測提供了 - 其餘的都是內置插件RxJS。

還有隔離的問題。如果將takeUntilmergeMap的外面,你將取消整個史詩,而不僅僅是特定的阿波羅客戶端。取而代之的是,我們需要把它裏面的mergeMap,因爲我們正在處理的一個承諾,我們需要使用Observable.from把它包起來。

export const languageTimeZoneEpic = (action$) => { 
    return action$.ofType(CHANGE_LANGUAGE) 
    .mergeMap(action => 
     Observable.from(
     client.mutate({ 
      mutation: languageMutation, 
      variables: { id: action.id, language: action.selected_language } 
     }) 
     .then(result => changeLanguageFulfilled(result)) 
     .catch(error => changeLanguageError(error)) 
    ) 
     .takeUntil(action$.ofType('END_LANGUAGE')) 
    ); 
}; 

但是,使用無極thencatch這樣可以說出來的地方 - 如果你喜歡與承諾的工作,我可能會建議對終極版,可觀察到的。當使用redux-observable時,如果我們沒有其他選擇(例如,我們不控制apollo-client API),我們通常只會使用Promises。在這些情況下,我通常會盡可能快地將它們包裝成Observable,然後其餘的都是正常的RxJS。

export const languageTimeZoneEpic = (action$) => { 
    return action$.ofType(CHANGE_LANGUAGE) 
    .mergeMap(action => 
     Observable.from(client.mutate({ 
     mutation: languageMutation, 
     variables: { id: action.id, language: action.selected_language } 
     })) 
     .map(result => changeLanguageFulfilled(result)) 
     .catch(error => Observable.of(
      changeLanguageError(error) 
     )) 
     .takeUntil(action$.ofType('END_LANGUAGE')) 
    ); 
}; 

有時,這意味着它是更冗長,但大多是關於不使用Promise的catch,因爲這可以讓你的代碼非常非常難的終極版,可觀察到的遵循。 「這是承諾還是可觀察到的嗎?」。當然,這只是我的意見:)


我認爲阿波羅的客戶端沒有辦法的實際上取消突變,因爲真正的承諾都沒有撤銷。這個代碼在技術上會忽略Promise的結果,而不是真正取消它(不可能)。

+0

>還有隔離的問題。如果您將takeUntil放置在mergeMap外部,您將取消整個Epic,而不僅僅是特定的apollo-client客戶端。 是啊我的一部分知道,但'mergeUntil'後放置'mergeMap' juste給了我一個錯誤,所以我想我會試一試。 – petithomme

+0

是的,現在,阿波羅客戶端無法自行取消突變。我喜歡你在第二個例子中所做的,但是就像你所說的那樣,它不會取消**突變,而是忽略**結果。我可能會試圖實現它,至少不會向用戶顯示更改,只是呈現他所做的最後一個操作。謝謝你的回答! – petithomme

+0

@petithomme非常歡迎! – jayphelps

相關問題