假设您有一个场景,您需要在页面的textarea中创建.csv输出...
所以我有2个数组,我循环嵌套在一起。嵌套循环的结果是传递ajax调用的查询...我需要将ajax调用的结果附加到textarea中。
我的问题是如何按照请求的顺序打印结果(基本上是查询数组中的顺序)
//example array to loop.
var outerQuery= ['A', 'B', 'C', 'D', 'E', 'F'];
var outerQueryLegth = outerQuery.length;
var innerQuery= ['1', '2', '3', '4', '5', '6'];
var innerQueryLegth = innerQuery.length;
//the textarea where im going to print the results in order later to open in excel as a .csv file
var $csvText= $('#some-text-area');
//outter loop
$.each(outerQuery, function(outerIndex, outer){
//Print the row
$csvText.append('Row' + outer +'\r\n\r\n');
//Nested inner loop (that should execute in order regarless or the time of the api call)
innerQuery.reduce(function(innerCallback, inner, innerIndex){
return innerCallback.then(function(){
return GoogleAnalyticsAPI(inner).then(function(response){
$csvText.append(response.column1 +',');
});
});//end inner callback
},Promise.resolve());
});
function GoogleAnalyticsAPI(val) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve({column1: val });
}, Math.floor((Math.random() * 1000) + 1));
});
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<textarea id="some-text-area" rows="20" cols="30"></textarea>
&#13;
正如你所看到的那样,片段中的结果非常糟糕 理想情况下,他们应该这样打印:
RowA
1,2,3,4,5,6
RowB
1,2,3,4,5,6
RowC
1,2,3,4,5,6
.
.
.
我从Ajax API calls in loop need to be executed in order得到的innerQuery.reduce非常感谢@ jfriend00
谢谢你们
答案 0 :(得分:1)
您可以使用.queue()
,.promise()
按顺序返回与数组中索引相对应的函数
//example array to loop.
var outerQuery = ['A', 'B', 'C', 'D', 'E', 'F'];
var outerQueryLegth = outerQuery.length;
var innerQuery = ['1', '2', '3', '4', '5', '6'];
var innerQueryLegth = innerQuery.length;
var $csvText = $('#some-text-area');
// create `"outerQuery"` queue
$csvText.queue("outerQuery", $.map(outerQuery, function(outer, index) {
return function(next) {
$(this).append((index > 0 ? '\r\n\r\n' : "")
+ 'Row' + outer + '\r\n\r\n')
// create `"innerQuery"` queue
.queue("innerQueue", $.map(innerQuery, function(inner, innerIndex) {
return function(_next) {
return GoogleAnalyticsAPI(inner).then(function(response) {
$csvText.append(response.column1 + ',');
// call `_next` function in `"innerQueue"`
}).then(_next);
}
})).dequeue("innerQueue").promise("innerQueue")
// call `next` function in `"outerQueue"`
// when all functions in current `innerIndex`
// of `innerQueue` array , `"innerQueue"` completes
.then(next)
}
})).dequeue("outerQuery");
function GoogleAnalyticsAPI(val) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve({
column1: val
});
}, Math.floor((Math.random() * 1000) + 1));
});
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<textarea id="some-text-area" rows="20" cols="30"></textarea>
&#13;
答案 1 :(得分:1)
您可以继续使用this prior answer中内部.reduce()
循环所使用的相同逻辑,并将其应用于外循环。此外,您可以使用普通的Javascript概念进行此同步。
这样做的关键是来自先前答案的内部.reduce()
循环返回一个仅在内循环中的所有链式异步操作完成时才解决的promise。您可以使用该承诺来控制和同步外部循环,如下所示:
//example array to loop.
var outerQuery= ['A', 'B', 'C', 'D', 'E', 'F'];
var innerQuery= ['1', '2', '3', '4', '5', '6'];
//the textarea where im going to print the results in order later to open in excel as a .csv file
var $csvText= $('#some-text-area');
//outer loop
outerQuery.reduce(function(outerP, outerItem) {
return outerP.then(function() {
//Print the row
$csvText.append('Row' + outerItem +'\r\n');
return innerQuery.reduce(function(innerP, inner, innerIndex){
return innerP.then(function(){
return GoogleAnalyticsAPI(inner).then(function(response){
$csvText.append(response.column1 +',');
});
});
}, Promise.resolve()).then(function() {
$csvText.append('\r\n\r\n');
});
});
}, Promise.resolve());
function GoogleAnalyticsAPI(val) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve({column1: val });
}, Math.floor((Math.random() * 500) + 1));
});
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<textarea id="some-text-area" rows="20" cols="30"></textarea>
&#13;