在React Component中显示并行Ajax请求的结果

时间:2016-09-13 15:05:11

标签: javascript ajax reactjs promise jsx

我试图在Reactjs中重写我的旧项目。由于我是初学者,这是我的第一个应用程序,我需要一些帮助来了解以React方式执行此操作的最佳方式以及如何改进自己和此演示项目。

以下是working demo

我想在Ajax请求完成后立即显示名称,而不是等待所有人在Promise中完成。

ListManager.js

import React, { Component } from 'react'
import List from './List'

export class ListManager extends Component {
  constructor (props, context) {
    super(props, context)
    this.state = {finaldata: []}
  }

  componentWillMount () {
    const id = [1, 2, 3, 4, 5]
    this.APIres(id)
  }

  APIres (ids) {
    Promise.all(ids.map(id => fetch('http://api.tvmaze.com/shows/' + id).then(resp => resp.json().then(data => data.name))
    )).then(data => {
      data.sort()
      this.setState({finaldata: Object.assign(this.state.finaldata, data)})
    })
  }

  render () {
    return (
      < div>
        <h3>{this.props.title}< /h3>
        <List data={this.state.finaldata} />
      < /div >
    )
  }
}

List.js

'use strict'
import React, { Component } from 'react'

const ListItem = ({ text }) => <li>{text}</li>

const List = ({ data }) => {
  const listNodes = data.map((value, index) => <ListItem text={value} key={index}></ListItem>)

  return <ul>{listNodes}</ul>
}
export default List

注意:id数组会带有example.com/#/?id=1,2,3,4之类的网址查询。我将使用react-router。

1 个答案:

答案 0 :(得分:1)

有方法

1,有序列 DEMO

所有提取同时开始(出于性能原因),但数据将按ID的顺序显示

  APIres (ids) {
    ids.map(id => fetch('http://api.tvmaze.com/shows/' + id).then(resp => resp.json()) )
    .reduce((sequence,promise)=>
    sequence.then(()=>promise)
    .then(({name})=>{
        this.setState({finaldata: [...this.state.finaldata, name]});
    }), Promise.resolve());
  }

无法保证2个顺序 DEMO

所有提取同时开始(出于性能原因),但数据将按请求响应的顺序出现,这可能与ids顺序不一致

  APIres (ids) {
    ids.forEach(id => fetch('http://api.tvmaze.com/shows/' + id).then(resp => resp.json())
     .then(({name})=>{
      this.setState({finaldata: [...this.state.finaldata, name]})
    }))
  }

在setState之前进行3次排序

数据将按请求响应的顺序显示,但排序将通过sort()

实现
  APIres (ids) {
    ids.forEach(id => fetch('http://api.tvmaze.com/shows/' + id).then(resp => resp.json())
     .then(({name})=>{
      this.setState({finaldata: [...this.state.finaldata, name].sort()})
    }))
  }