में नेस्टेड एपीआई कॉल को कैसे संभालें I अंग्रेजी सीखने वाली साइट के लिए पदों के निर्माण और संपादन को संभालने के लिए फेसबुक के फ्लक्स डिस्पैचर का उपयोग करके एक सरल सीआरयूडी ऐप बना रहा हूं। मैं वर्तमान में एक एपीआई कि इस तरह दिखता है के साथ काम कर रहा हूँ:फ्लक्स
/posts/:post_id
/posts/:post_id/sentences
/sentences/:sentence_id/words
/sentences/:sentence_id/grammars
अनुप्रयोग के लिए शो और संपादित पृष्ठों पर, मैं के सभी के रूप में दिए गए पद के लिए सभी जानकारी को दिखाने के लिए और साथ ही सक्षम होने के लिए करना चाहते हैं यह वाक्यों और वाक्यों के शब्दों और व्याकरण विवरण सभी एक ही पृष्ठ पर है।
जो मुद्दा मैं मार रहा हूं वह यह पता लगा रहा है कि इस डेटा को इकट्ठा करने के लिए आवश्यक सभी एसिंक कॉल कैसे शुरू करें, और उसके बाद मुझे सभी स्टोर्स से डेटा को एक ही ऑब्जेक्ट में लिखना है जिसे मैं राज्य के रूप में सेट कर सकता हूं मेरा शीर्ष स्तर घटक। मुझे क्या करना करने की कोशिश कर रहा है की एक वर्तमान (भयानक) उदाहरण यह है:
शीर्ष स्तर PostsShowView:
class PostsShow extends React.Component {
componentWillMount() {
// this id is populated by react-router when the app hits the /posts/:id route
PostsActions.get({id: this.props.params.id});
PostsStore.addChangeListener(this._handlePostsStoreChange);
SentencesStore.addChangeListener(this._handleSentencesStoreChange);
GrammarsStore.addChangeListener(this._handleGrammarsStoreChange);
WordsStore.addChangeListener(this._handleWordsStoreChange);
}
componentWillUnmount() {
PostsStore.removeChangeListener(this._handlePostsStoreChange);
SentencesStore.removeChangeListener(this._handleSentencesStoreChange);
GrammarsStore.removeChangeListener(this._handleGrammarsStoreChange);
WordsStore.removeChangeListener(this._handleWordsStoreChange);
}
_handlePostsStoreChange() {
let posts = PostsStore.getState().posts;
let post = posts[this.props.params.id];
this.setState({post: post});
SentencesActions.fetch({postId: post.id});
}
_handleSentencesStoreChange() {
let sentences = SentencesStore.getState().sentences;
this.setState(function(state, sentences) {
state.post.sentences = sentences;
});
sentences.forEach((sentence) => {
GrammarsActions.fetch({sentenceId: sentence.id})
WordsActions.fetch({sentenceId: sentence.id})
})
}
_handleGrammarsStoreChange() {
let grammars = GrammarsStore.getState().grammars;
this.setState(function(state, grammars) {
state.post.grammars = grammars;
});
}
_handleWordsStoreChange() {
let words = WordsStore.getState().words;
this.setState(function(state, words) {
state.post.words = words;
});
}
}
और यहाँ है मेरी PostsActions.js - अन्य संस्थाओं (वाक्य, व्याकरण,
let api = require('api');
class PostsActions {
get(params = {}) {
this._dispatcher.dispatch({
actionType: AdminAppConstants.FETCHING_POST
});
api.posts.fetch(params, (err, res) => {
let payload, post;
if (err) {
payload = {
actionType: AdminAppConstants.FETCH_POST_FAILURE
}
}
else {
post = res.body;
payload = {
actionType: AdminAppConstants.FETCH_POST_SUCCESS,
post: post
}
}
this._dispatcher.dispatch(payload)
});
}
}
मुख्य मुद्दा यह है कि फ्लक्स डिस्पैचर फेंकता एक अपरिवर्तनीय त्रुटि SentencesActions.fetch
_handlePostsStoreChange
कॉलबैक में कहा जाता है "एक प्रेषण के बीच में प्रेषण नहीं कर सकते" है: शब्द) भी इसी तरह ActionCreators है कि एक समान तरीके से काम करते हैं becau से पहले की क्रिया के लिए प्रेषण कॉलबैक से पहले प्रेषण क्रिया विधि एक प्रेषण को ट्रिगर करती है।
मुझे पता है कि मैं _.defer
या setTimeout
की तरह कुछ का उपयोग करके इसे ठीक कर सकते हैं - लेकिन वास्तव में ऐसा लगता है कि जैसे मैं बस यहाँ मुद्दा पैचिंग कर रहा हूँ। इसके अलावा, मैंने कार्यों में अपने सभी fetching तर्क को करने पर विचार किया, लेकिन यह भी सही नहीं लग रहा था, और त्रुटि को और अधिक कठिन संभालने में मदद करेगा। मेरे पास मेरी प्रत्येक संस्थाएं अपने स्वयं के स्टोर और कार्यों में अलग हो गई हैं - क्या प्रत्येक इकाई के संबंधित स्टोर से मुझे जो चाहिए उसे लिखने के लिए घटक स्तर में कुछ रास्ता नहीं होना चाहिए?
किसी भी व्यक्ति से किसी भी सलाह के लिए खोलें जिसने कुछ ऐसा किया है!
क्या आपने 'waitFor' का उपयोग करने का प्रयास किया है? https://facebook.github.io/flux/docs/dispatcher.html – knowbody
@nownow हाँ, मैंने 'waitFor' का उपयोग करने का प्रयास किया है, लेकिन वास्तव में यह समस्या का समाधान नहीं कर रहा था, क्योंकि मुद्दा यह है कि पहले व्यक्ति को खत्म करने से पहले दूसरी कार्रवाई भेज दी जाती है। हालांकि, शायद 'WaitFor' की मेरी समझ गलत है और मैं इसे सही तरीके से उपयोग नहीं कर रहा हूं? – joeellis
@ जॉयेलिस: क्या आपके लिए एक जेएसफ़िल्ड डेमो को एक साथ रखना संभव है कृपया अपनी समस्या की स्थिति का प्रदर्शन करें? –