当前位置:  开发笔记 > 前端 > 正文

Cycle.js HTTP在添加加载指示符后发送多个请求

如何解决《Cycle.jsHTTP在添加加载指示符后发送多个请求》经验,为你挑选了1个好方法。

我一直在尝试创建一些cycle.js示例作为嵌套对话框,并使用选择框在它们之间切换.

其中一个对话是官方Github HTTP搜索示例的克隆.

另一个对话是一个更基本的对话,没有HTTP,只有DOM.

我觉得我绕着2号换了我的头,但我对Rx来说相当新,所以可能做得不正确或天真.

在我向搜索页面添加加载指示器之前,这一切似乎都运行良好.

为此,我转过身来:

  const vTree$ = responses.HTTP
    .filter(res$ => res$.request.indexOf(GITHUB_SEARCH_API) === 0)
    .flatMapLatest(x => x)
    .map(res => res.body.items)
    .startWith([])
    .map(results =>
      h('div.wrapper', {}, [
        h('label.label', {}, 'Search:'),
        h('input.field', {type: 'text'}),
        h('hr'),
        h('section.search-results', {}, results.map(resultView)),
      ])
    )

进入:

  const searchResponse$ = responses.HTTP
    .filter(res$ => res$.request.indexOf(GITHUB_SEARCH_API) === 0)
    .flatMapLatest(x => x)
    .map(res => res.body.items)
    .startWith([])

  const loading$ = searchRequest$.map(true).merge(searchResponse$.map(false))

  // Convert the stream of HTTP responses to virtual DOM elements.
  const vtree$ = loading$.withLatestFrom(searchResponse$, (loading, results) =>
      h('div.wrapper', {}, [
        h('label.label', {}, 'Search:'),
        h('input.field', {type: 'text'}),
        h('span', {}, loading ? 'Loading...' : 'Done'),
        h('hr'),
        h('section.search-results', {}, results.map(resultView)),
      ])
    )

我现在有2个问题

    每次更改复选框时,会将"复选框值设置为"和"路径已更改"消息记录两次.

    HTTP请求日志仅触发一次,但如果您在Dev Tools中观察网络活动,则会同时看到两个GET请求.

谢谢你的帮助!

编辑:解决了我自己的问题.见下面的答案.



1> SkaterDad..:

我最终通过从头开始重建我的整个应用程序来解决这个问题,直到找到了突破点.

我学到的是你需要添加.share()到任何可观察的流,这些流将被多个下游的observable订阅/映射/等.

  const searchRequest$ = DOM.select('.field').events('input')
    .debounce(500)
    .map(ev => ev.target.value.trim())
    .filter(query => query.length > 0)
    .map(q => GITHUB_SEARCH_API + encodeURI(q))
    .share() //needed because multiple observables will subscribe

  // Get search results from HTTP response.
  const searchResponse$ = HTTP
    .filter(res$ => res$ && res$.request.url.indexOf(GITHUB_SEARCH_API) === 0)
    .flatMapLatest(x => x) //Needed because HTTP gives an Observable when you map it
    .map(res => res.body.items)
    .startWith([])
    .share() //needed because multiple observables will subscribe

  //loading indication.  true if request is newer than response
  const loading$ = searchRequest$.map(true).merge(searchResponse$.map(false))
    .startWith(false)
    .share()

  //Combined state observable which triggers view updates
  const state$ = Rx.Observable.combineLatest(searchResponse$, loading$,
    (res, loading) => {
      return {results: res, loading: loading}
    })

  //Generate HTML from the current state
  const vtree$ = state$
    .map(({results, loading}) =>
      .........

推荐阅读
无名有名我无名_593
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有