2017-01-16 10 views
16

मेरे पास @ngrx प्रभाव से संबंधित एक बहुत ही बुनियादी सवाल है: प्रभाव के निष्पादन के दौरान होने वाली त्रुटि को अनदेखा कैसे करें जिससे कि यह भविष्य के प्रभाव निष्पादन को प्रभावित न करे?ngrx प्रभाव त्रुटि हैंडलिंग

मेरी स्थिति निम्नानुसार है: मेरे पास एक क्रिया (LOGIN) है और उस क्रिया को सुनने का प्रभाव है। अगर इस प्रभाव के अंदर कोई त्रुटि होती है, तो मैं इसे अनदेखा करना चाहता हूं। जब इस त्रुटि के बाद दूसरी बार LOGIN प्रेषित किया जाता है, तो प्रभाव दूसरी बार निष्पादित किया जाना चाहिए। यह था करने के लिए

मेरा पहला प्रयास:

@Effect() 
    login$ = this.actions$ 
    .ofType('LOGIN') 
    .flatMap(async() => { 
     console.debug('LOGIN'); 
     // throw an error 
     let x = [];x[0](); 
    }) 
    .catch(err => { 
     console.error('Error at login', err); 
     return Observable.empty(); 
    }); 

भेजने प्रवेश पहली बार फेंकता है और अपेक्षा के अनुरूप त्रुटि पकड़ता,। हालांकि, अगर मैं बाद में दूसरी बार लॉग इन भेजता हूं, तो कुछ भी नहीं होता है; प्रभाव निष्पादित नहीं किया गया है।

इसलिए मैं निम्नलिखित की कोशिश की:

.catch(err => { 
     return this.login$; 
    }); 

, लेकिन यह एक अंतहीन लूप में परिणाम है ... क्या आप जानते हैं कैसे प्रभाव निष्पादन बाद में रोकने के बिना त्रुटि को पकड़ने के लिए?

+0

मैं ngrx पता नहीं है लेकिन आप शायद सिर्फ '.retry()' धारा के बजाय पकड़ने पर कर सकते हैं। – Gluck

उत्तर

14

ngrx बुनियादी ढांचे को एप्लिकेशन की NgModuleEffectsModule.run का उपयोग कर में आयात प्रदाता के माध्यम से प्रभाव का सदस्य बनता।

जब अवलोकन योग्य त्रुटियां और catch एक खाली अस्थिर लौटाता है, तो रचनाकृत अवलोकन योग्य और इसके ग्राहक सदस्यता समाप्त कर दिए जाते हैं - यह Observable Contract का हिस्सा है। और यही कारण है कि आप अपने प्रभाव में LOGIN कार्रवाइयों का कोई और प्रबंधन नहीं देखते हैं। प्रभाव पूरा होने पर सदस्यता समाप्त हो गई है और ngrx आधारभूत संरचना पुन: सदस्यता नहीं लेती है।

import { Actions, Effect, toPayload } from "@ngrx/effects"; 

@Effect() 
login$ = this.actions$ 
    .ofType('LOGIN') 
    .map(toPayload) 
    .flatMap(payload => Observable 
    .from(Promise.reject('Boom!')) 
    .catch(error => { 
     console.error('Error at login', error); 
     return Observable.empty(); 
    }) 
    }); 

catch भीतरी नमूदार में बना एक खाली नमूदार चपटा देखेंगे /, प्रभाव में विलय कर दिया तो कोई कार्रवाई नहीं की:

आमतौर पर, आप flatMap (अब mergeMap कहा जाता है) के अंदर से निपटने त्रुटि के लिए होता है उत्सर्जित किया जाएगा।

1

यह है मैं कैसे संभाल विकल्प या सूचना प्राप्त नहीं observables है कि किसी भी डेटा नहीं मिला पर अधिसूचित:

public listenCampaignValueChanged(emitOnEmpty: boolean = false): Observable<CampaignsModelExt> { 
     var campaignIdSelected$ = this.ngrxStore.select(store => store.appDb.uiState.campaign.campaignSelected) 
     var campaigns$ = this.ngrxStore.select(store => store.msDatabase.sdk.table_campaigns); 
     return campaignIdSelected$ 
      .combineLatest(campaigns$, (campaignId: number, campaigns: List<CampaignsModelExt>) => { 
       return campaigns.find((i_campaign: CampaignsModelExt) => { 
        return i_campaign.getCampaignId() == campaignId; 
       }); 
      }).flatMap(v => (v ? Observable.of(v) : (emitOnEmpty ? Observable.of(v) : Observable.empty()))); 
    } 
2

@Effect धारा पूरा किया जाता है जब त्रुटि होती है, किसी भी आगे की कार्रवाई को रोकने के ।

समाधान एक डिस्पोजेबल स्ट्रीम पर स्विच करना है। यदि डिस्पोजेबल स्ट्रीम में कोई त्रुटि होती है तो यह ठीक है, क्योंकि मुख्य @Effect स्ट्रीम हमेशा जिंदा रहता है, और भविष्य की क्रियाएं निष्पादित होती रहती हैं।

@Effect() 
login$ = this.actions$ 
    .ofType('LOGIN') 
    .switchMap(action => { 

     // This is the disposable stream! 
     // Errors can safely occur in here without killing the original stream 

     return Rx.Observable.of(action) 
      .map(action => { 
       // Code here that throws an error 
      }) 
      .catch(error => { 
       // You could also return an 'Error' action here instead 
       return Observable.empty(); 
      }); 

    }); 

इस ब्लॉग पोस्ट में इस तकनीक पर अधिक जानकारी: The Quest for Meatballs: Continue RxJS Streams When Errors Occur

संबंधित मुद्दे