2015-11-19 6 views
8

私はリアクションプログラミングとcycle.jsで対処し、this tutorialからボックスに従う人を実装しようとしています。しかし、私は、適切な実装(および学習目的)のために、1つのデータがないことを理解しました:完全なユーザー名。私は順番にユーザーを取得し、次にサーバーからフルユーザーデータを取得することで取得できます。命令的なスタイルで私はこのような何かをするでしょう: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 ... */) 

しかし私はどのようにそれを周期的に行うのですか? 私はドライバーをフェッチ使用して、このような何かしようとしている:TypeError: Already readgetJSON

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

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

であると私はいつものようないくつかの不可解な(私にとっては)エラーを取得しています

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$, 
    }; 
} 

を。それはどういう意味ですか、どうすれば適切に処理できますか?

答えて

9

あなたはかなり近くでした。リクエストとしてstartWith(null)を削除し、2番目のレスポンスを取得する必要があります(これには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 $'が 'listResponse $'が何かを放射するのを待ってからチェーン内の次のことをするだけであることを正しく理解していますか? – 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ドライバーだった、とNOT @cycle/httpドライバー。次に、少しの検索で、propheadのメソッドを提供するramda npmライブラリが作成されました。

関連する問題