React中有多个异步XMLHttpRequests

时间:2017-08-21 00:33:25

标签: javascript reactjs

我做了一个基于examples的多异步XMLHttpReqest示例,我找到了:

var  URL=["https://api.github.com/users/github","https://api.github.com/users/github/repos"];
var xhr = [null, null];
for (var i = 0; i < 2; i++) {
  (function(i) {
xhr[i] = new XMLHttpRequest();
xhr[i].open("GET", URL[i], true);
xhr[i].onload = function (e) {
  if (xhr[i].readyState === 4) {
    if (xhr[i].status === 200) {
      console.log(xhr[i].responseText);
    } else {
      console.error(xhr[i].statusText);
    }
  }
};
xhr[i].onerror = function (e) {
  console.error(xhr[i].statusText);
};
xhr[i].send(null);
  })(i);
}

事实是我在反应中实现它时遇到问题,因为我无法将this.setState({json_objs[i]:JSON.parse(xhr[i].responseText})赋值给对象数组。

这是我的反应代码,由于分配值而无法正常工作:

import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';




class ImageViewer extends React.Component {
    constructor() {
        super();
        this.state = {
            json_objs : [null,null],
            links:["https://api.github.com/users/github/repos","https://api.github.com/users/github"]
			
        }
    }
	componentDidMount() {
    var xhr = [null, null]
    for (var i = 0; i < 2; i++) {
    (function(i) {
		xhr[i] = new XMLHttpRequest();
		xhr[i].open("GET", this.state.link, true);
		xhr[i].onload = function (e) {
			if (xhr[i].readyState === 4) {
				if (xhr[i].status === 200) {
					this.setState({ json_objs[i]:JSON.parse(xhr[i].responseText)});
				} else {
				console.error(xhr[i].statusText);
				}
			}
		}.bind(this);
		xhr[i].onerror = function (e) {
		console.error(xhr[i].statusText);
		};
		xhr[i].send(null);
      })(i);
}

		 render() {
           if (!this.state.json_objs[0] || !this.state.json_objs[1]) {
				return <div>Loading...</div>;
		}
		return(
<div>
<div><h1>{this.state.json_objs[1].email}</h1></div>
				   {this.state.json_objs[0].sort(function(a, b){var keyA = new Date(a.updated_at),keyB = new Date(b.updated_at);if(keyA > keyB) return -1;if(keyA < keyB) return 1;return 0;}).map((obj, index)  => {
                            return (
								 <div key={index}>
									<div>{obj.name}</div>
									<div>{(new Date(obj.updated_at)).toString()}</td>
								</div>
                            )
                    })}
</div>
    )
}}
ReactDOM.render(<ImageViewer />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

我一直在阅读有关反应中的modyfing数组,但我在实现它时遇到了问题。

1 个答案:

答案 0 :(得分:2)

我认为Promise在这里会有所帮助。在Promise中包装每个XHR请求,使用Promise.all()等待它们都完成,然后将结果设置为状态(它将使用响应对象数组解析):

Promise.all([0, 1].map((index) => {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest()
    xhr.open("GET", this.state.links[index], true)
    xhr.onload = function() {
      if (xhr.readyState === 4) {
        if(xhr.status === 200) {
          resolve(JSON.parse(xhr.responseText))
        } else {
          reject(xhr.statusText)
        }
    }
  })
})).then((json_objs) => {
  this.setState({ json_objs }, () => {
     console.log('json_objs => ', this.state.json_objs)
  })
}).catch(err => console.error(err))