json.orderItem.length == 2
,因此触发2个HTTP
请求
如果我一个接一个地发出这两个请求(不是循环),我会收到这两个单独的响应:
1'产品名称1,部件编号2342'
2'产品名称2,部件编号8789'
我想在这些响应返回时将它们连接起来,这样,在某个时候,我可以将所有响应记录为一个字符串
我怎样才能做到这一点?
目前,我无法确定是否所有请求都已完成,因此无法记录最终的String
。
包裹在循环中的请求。。
var f = (function(){
var xhr = [];
var test = '';
for (i = 0; i < json.orderItem.length; i++){
(function (i){
xhr[i] = new XMLHttpRequest();
url = '/products/byId/' + json.orderItem[i].productId;
xhr[i].open("GET", url, true);
xhr[i].onreadystatechange = function () {
if (xhr[i].readyState == 4 && xhr[i].status == 200) {
test += JSON.parse(xhr[i].responseText).entry[0].name + ', ' + JSON.parse(xhr[i].responseText).entry[0].partNumber;
}
};
xhr[i].send();
})(i);
}
})();
使用javascript闭包:
闭包是指独立(自由)变量的函数。换句话说,闭包中定义的函数"记住"创建它的环境。
取自:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures
闭包在Javascript中是一个非常强大的概念,所以如果你不熟悉它们,我建议你去读一下。
现在,我们如何使用它来解决您的问题?
var f = (function() {
// scope a
var xhr = [],
successfulRequests = 0,
responseString = "";
for (i = 0; i < json.orderItem.length; i++){
(function (i) {
xhr[i] = new XMLHttpRequest();
url = '/products/byId/' + json.orderItem[i].productId;
xhr[i].open("GET", url, true);
xhr[i].onreadystatechange = function () {
if (xhr[i].readyState == 4 && xhr[i].status == 200) {
// scope b
// track successful requests here
successfulRequests++; // "remembered" through closure
responseString += xhr[i].responseText; // "remembered" through closure
if(successfulRequests == json.orderItem.length) {
console.log(responseString);
}
}
};
xhr[i].send();
})(i);
}
})();
scopeA中声明的变量通过闭包在scopeB中被记住。
注意:此实现只会在所有请求成功完成后记录responseString。如何处理请求失败取决于您,但希望您现在应该知道如何处理。
命名您的操作,并使用一个公共位置来存储结果,以及完成所有操作时的回调;alert()用于这个简单的例子:
var test = '';
function grab(i, done){
var xhr = new XMLHttpRequest(),
url = '/products/byId/' + json.orderItem[i].productId;
xhr.open("GET", url, true);
xhr.onload= function () {
var ob=JSON.parse(xhr.responseText);
test += ob.entry[0].name + ', ' +ob.entry[0].partNumber;
if(json.orderItem[i+1]){ //more items, pass forward:
grab(i+1, done);
}else{ //no more, run run done()
done(test);
}
};
xhr.send();
}//end grab
grab(0, alert);
您可能希望对其进行更多的抽象,以传递到集合或结果列表中,从而使其更易于重用,但在异步操作中,可以使用相同的基本步骤序列来保持顺序。
你可以变得更花哨,一次把它们全部发送出去,然后在它们进来的时候订购,但这有点高级。看看Promises,让类似的事情变得相对容易。