2015-11-19 7 views
8

मैं प्रतिक्रियाशील प्रोग्रामिंग और cycle.js के साथ घूमने के लिए नया हूं, this tutorial से बॉक्स का पालन करने के लिए कौन सा कार्यान्वित करने का प्रयास कर रहा हूं। लेकिन मुझे समझ में आया कि उचित कार्यान्वयन (और सीखने के उद्देश्यों) के लिए मेरे पास डेटा का एक टुकड़ा नहीं है: पूर्ण उपयोगकर्ता नाम। मैं अनुक्रमिक रूप से उपयोगकर्ताओं को प्राप्त कर सकता हूं और फिर सर्वर से पूर्ण उपयोगकर्ता डेटा प्राप्त कर सकता हूं। अनिवार्य शैली में मैं ऐसा कुछ करूंगा:Cycle.js में अनुक्रमिक रूप से डेटा का अनुरोध कैसे करें?

fetch(`https://api.github.com/users`) 
    .then(data => data.json()) 
    .then(users => fetch(users[0].url)) 
    .then(data => data.json()) 
    .then(/* ... work with data ... */) 

लेकिन मैं इसे चक्र में कैसे कर सकता हूं? मैं इस तरह चालक लाने उपयोग कर रहा हूँ और कोशिश कर कुछ:

function main({ DOM, HTTP }) { 
    const users = `https://api.github.com/users`; 

    const refresh$ = DOM.select(`.refresh`).events(`click`) 

    const response$ = getJSON({ key: `users` }, HTTP) 

    const userUrl$ = response$ 
    .map(users => ({ 
     url: R.prop(`url`, R.head(users)), 
     key: `user`, 
    })) 
    .startWith(null) 

    const request$ = refresh$ 
    .startWith(`initial`) 
    .map(_ => ({ 
     url: `${users}?since=${random(500)}`, 
     key: `users`, 
    })) 
    .merge(userUrl$) 

    const dom$ = ... 

    return { 
    DOM: dom$, 
    HTTP: request$, 
    }; 
} 

जहां getJSON

function getJSON(by, requests$) { 
    const type = capitalize(firstKey(by)); 

    return requests$ 
    [`by${type}`](firstVal(by)) 
    .mergeAll() 
    .flatMap(res => res.json()); 

है और मैं हमेशा की तरह कुछ गुप्त (मेरे लिए) त्रुटि हो रही है: TypeError: Already read। इसका क्या अर्थ है और मैं इसे कैसे ठीक से संभाल सकता हूं?

उत्तर

9

आप काफी करीब थे। आपको अनुरोध के रूप में startWith(null) को हटाने की आवश्यकता है, और दूसरी प्रतिक्रिया को पकड़ना (आप उस के लिए getJSON खो रहे थे)।

function main({ DOM, HTTP }) { 
    const usersAPIPath = `https://api.github.com/users`; 

    const refresh$ = DOM.select(`.refresh`).events(`click`); 

    const userResponse$ = getJSON({ key: `user` }, HTTP); 
    const listResponse$ = getJSON({ key: `users` }, HTTP); 

    const userRequest$ = listResponse$ 
    .map(users => ({ 
     url: R.prop(`url`, R.head(users)), 
     key: `user`, 
    })); 

    const listRequest$ = refresh$ 
    .startWith(`initial`) 
    .map(_ => ({ 
     url: `${usersAPIPath}?since=${Math.round(Math.random()*500)}`, 
     key: `users`, 
    })); 

    const dom$ = userResponse$.map(res => h('div', JSON.stringify(res))); 

    return { 
    DOM: dom$, 
    HTTP: listRequest$.merge(userRequest$), 
    }; 
} 
+0

धन्यवाद, यह काम करता है! लेकिन यह अभी भी मेरे लिए जादू का प्रतीत होता है। क्या मैं सही ढंग से समझता हूं कि 'userRequest $' कुछ भी उत्सर्जित करने के लिए 'सूची रिस्पॉन्स $' के लिए इंतजार कर रहा है और फिर श्रृंखला में अगला क्या है? – kibin

+1

सही। यह 'listResponse $ 'से एक नए अनुरोध पर एक ईवेंट को मानचित्र करता है। –

+0

समझा। फिर से धन्यवाद, मुझे वास्तव में cycle.js पसंद है और इसमें खोदना जारी रहेगा। – kibin

0

क्योंकि पूछताछ करने मन जानना चाहता हूँ ... यहाँ एक पूरा काम कर उदाहरण है:

import Cycle from '@cycle/rx-run'; 
import {div, button, makeDOMDriver} from '@cycle/dom'; 
import {makeFetchDriver} from '@cycle/fetch'; 
import R from 'ramda' 

function main({DOM, HTTP}) { 

    const usersAPIPath = 'https://api.github.com/users'; 
    const refresh$ = DOM.select('button').events('click'); 

    const userResponse$ = getJSON({ key: 'user' }, HTTP); 
    const listResponse$ = getJSON({ key: 'users' }, HTTP); 

    const userRequest$ = listResponse$ 
    .map(users => ({ 
     url: R.prop('url', R.head(users)), 
     key: 'user', 
    })); 

    const listRequest$ = refresh$ 
    .startWith('initial') 
    .map(_ => ({ 
     url: `${usersAPIPath}?since=${Math.round(Math.random()*500)}`, 
     key: 'users', 
    })); 

    const dom$ = userResponse$.map(res => div([ 
    button('Refresh'), 
    div(JSON.stringify(res)) 
    ])); 

    return { 
    DOM: dom$, 
    HTTP: listRequest$.merge(userRequest$) 
    }; 

    function getJSON(by, requests$) { 
    return requests$.byKey(by.key) 
     .mergeAll() 
     .flatMap(res => res.json()); 
    } 
} 

Cycle.run(main, { 
    DOM: makeDOMDriver('#main-container'), 
    HTTP: makeFetchDriver() 
}); 

यह मुझे कुछ समय लिया यह पता लगाने की HTTP@cycle/fetch ड्राइवर था, और नहीं @cycle/http ड्राइवर। इसके बाद, कुछ खोज ने ramda एनपीएम लाइब्रेरी को prop और head विधियों को प्रदान किया।

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