【问题标题】:How to request data sequentially in Cycle.js?如何在 Cycle.js 中按顺序请求数据?
【发布时间】:2016-02-22 06:42:36
【问题描述】:

我是响应式编程的新手,我在玩cycle.js,试图实现this tutorial 中的谁关注框。但我明白,为了正确实施(和学习目的),我没有一条数据:完整的用户名。我可以通过顺序获取用户然后从服务器获取完整用户数据来获取它。在命令式风格中,我会做这样的事情:

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

但是我如何在循环中做到这一点? 我正在使用 fetch 驱动程序并尝试这样的事情:

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。这是什么意思,如何正确处理?

【问题讨论】:

    标签: javascript reactive-programming rxjs cyclejs


    【解决方案1】:

    你已经很接近了。您只需将 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$),
      };
    }
    

    【讨论】:

    • 谢谢,它有效!但这对我来说仍然是一种魔法。我是否正确理解 userRequest$ 只是等待 listResponse$ 发出任何内容,然后执行链中的下一步?
    • 正确。它将来自 listResponse$ 的事件映射到新请求。
    • 明白。再次感谢,我真的很喜欢 cycle.js 并将继续深入研究它。
    • 我终于弄清楚这里使用的cyclejs HTTP驱动是@cycle/fetch驱动:github.com/cyclejs/cycle-fetch-driver
    【解决方案2】:

    因为好奇的人想知道......这是一个完整的工作示例:

    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 驱动程序。接下来,稍微搜索了一下,找到了提供prophead 方法的ramda npm 库。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多