2016-12-01 9 views
6

मेरे उपयोग मामला है:RxJs observables: कुछ और async के बाद retryWhen चलाने का अनुरोध करता है

  1. उपयोगकर्ता हमारे एपीआई जो क्योंकि जेडब्ल्यूटी समाप्त हो रही है (एक केवल Http कुकी के रूप में पारित कर दिया) के विफल रहता है से संपत्ति का अनुरोध करता है - एपीआई 401 स्थिति कोड लौटाने ।
  2. हम अपने क्लाइंट से auth0 के अनुरोध के साथ एक नया जेडब्ल्यूटी प्राप्त करने के लिए एक refresh_token का उपयोग करके फिर से (बिना उपयोगकर्ता के कुछ भी) प्रमाणित करते हैं और प्रमाणित करते हैं।
  3. हम अपने एपीआई को उस नए जेडब्ल्यूटी को समय-समय पर बदलने के लिए httpOnly कुकी के रूप में सेट करने के लिए भेजते हैं।
  4. हम तो कदम 1.

मैं redux-observable के साथ मेरी Redux अनुप्रयोग के भीतर observables उपयोग करने के लिए कोशिश कर रहा हूँ में मूल अनुरोध एपीआई के लिए किए गए उपयोगकर्ता पुन: प्रयास करना चाहते हैं। यदि आप उपर्युक्त उपयोगकर्ता प्रवाह कार्य करने का एक और तरीका सोच सकते हैं तो मुझे यह सुनकर खुशी होगी कि कैसे।

एनबी। अब तक मैं सक्षम कदम 4. जोड़ने के लिए चरणों 1, 2 और 3 नहीं बल्कि एक तरह से के बारे में सुनिश्चित पूरा करने के लिए rxjs V5

export const fetchAssetListEpic = (action$, store) => { 
 
    return action$.ofType('FETCH_ASSET_LIST') 
 
    .switchMap(action => { 
 
    const options = { 
 
     crossDomain: true, 
 
     withCredentials: true, 
 
     url: uriGenerator('assetList', action.payload) 
 
    }; 
 
    return ajax(options); 
 
    }) 
 
    .map(fetchAssetListSuccess) 
 
    .retryWhen(handleError) 
 
    .catch(redirectToSignIn); 
 
}; 
 

 
function handleError(err) { 
 
    return (err.status === 401) ? 
 
    /* Authenticate here [Step 2] */ 
 
    /* Send new JWT to API [Step 3] */ 
 
    /* If successful make original request again [Step 4] */ 
 
    : 
 
    Observable.throw(err); 
 
} 
 
    
 
function redirectToSignIn() { 
 
    /*I will redirect here*/ 
 
}

का उपयोग कर इम मैं मार्क लेकिन किसी भी मदद पूरी तरह से बंद हो सकता है बहुत अच्छा होगा!

उत्तर

6

वैसे एक चीज जो आप शायद नहीं करना चाहेंगे, त्रुटि को इसे शीर्ष स्तर की स्ट्रीम में लाने की अनुमति है। यहां तक ​​कि यदि आप catch करते हैं तो भी आपने शीर्ष स्तर की स्ट्रीम को प्रभावी ढंग से मार दिया है। इसलिए जब तक कि आपका रीडायरेक्ट प्रतिक्रिया-राउटर जैसी किसी चीज़ के माध्यम से मुलायम व्यक्ति के बजाय हार्ड रीडायरेक्ट नहीं कर रहा है, तो आप इस महाकाव्य का उपयोग करने में सक्षम नहीं होंगे।

इस प्रकार मैं कहूँगा कि आप तर्क के सबसे switchMap भीतर समझाया करना चाहते हैं:

function withAuthorizedFlow(source) { 
    return source 
    .map(fetchAssetListSuccess) 
    // retryWhen takes a callback which accepts an Observable of errors 
    // emitting a next causes a retry, while an error or complete will 
    // stop retrying 
    .retryWhen(e => e.flatMap(err => 
     Observable.if(
     // Returns the first stream if true, second if false 
     () => err.status === 401, 
     reauthenticate, // A stream that will emit once authenticated 
     Observable.throw(err) // Rethrow the error 
    )) 
    ) 
    .catch(redirectToSignIn); 
} 

/** Within the epic **/ 
.switchMap(({payload}) => { 
    const options = { 
    crossDomain: true, 
    withCredentials: true, 
    url: uriGenerator('assetList', payload) 
    }; 

    // Invoke the ajax request 
    return ajax(options) 
    // Attach a custom pipeline here 
    // Not strictly necessary but it keeps this method clean looking. 
    .let(withAuthorizedFlow); 
}) 

let के उपयोग के ऊपर पूरी तरह से वैकल्पिक है, मैं इसे में फेंक दिया समारोह को साफ करने के। अनिवार्य रूप से हालांकि आप आंतरिक धारा में त्रुटि को शामिल करना चाहते हैं ताकि वह बाहरी को रोक न सके। मुझे यकीन नहीं है कि आप किस ajax लाइब्रेरी का उपयोग कर रहे हैं लेकिन आपको यह भी पुष्टि करनी चाहिए कि वास्तव में यह ठंडा Observable लौटाएगा अन्यथा आपको ब्लॉक में इसे retryWhen पर काम करने के लिए इसे लपेटने की आवश्यकता होगी।

+0

वास्तव में अच्छा जवाब - मजाकिया बात: न तो '.if' और' .let' दस्तावेज प्रतीत होता है (http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html) –

+0

दिलचस्प , उन दस्तावेजों को उत्पन्न करने वाले ऑटो के नीचे की ओर मुझे लगता है कि – paulpdaniels

+0

इस @paulpdaniels के लिए धन्यवाद, यह बहुत अच्छा लग रहा है! मुझे अभी तक इसे लागू करने का मौका मिला है, लेकिन जब मुझे मौका मिलता है तो अपडेट हो जाएगा। हालांकि स्वीकार किए गए उत्तर के रूप में इसे चिह्नित करने के लिए खुश है :) – Jbarget

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